From 3331a68859fd71047bb1f309048960b48eab2d83 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=2E=C3=87a=C4=9Flar=20Onur?= Date: Thu, 15 Apr 2010 20:39:24 +0000 Subject: [PATCH] bump to latest stable and change repository layout --- COPYING | 340 - ChangeLog | 563 - Makefile | 130 +- README | 34 - README.decnet | 33 - README.distribution | 95 - README.iproute2+tc | 119 - README.lnstat | 81 - RELNOTES | 168 - configure | 27 - doc/Makefile | 55 - doc/Plan | 16 - doc/SNAPSHOT.tex | 1 - doc/actions/actions-general | 254 - doc/actions/dummy-README | 155 - doc/actions/gact-usage | 79 - doc/actions/mirred-usage | 71 - doc/api-ip6-flowlabels.tex | 429 - doc/arpd.sgml | 130 - doc/do-psnup | 16 - doc/ip-cref.tex | 3316 ----- doc/ip-tunnels.tex | 469 - doc/nstat.sgml | 110 - doc/preamble.tex | 26 - doc/rtstat.sgml | 52 - doc/ss.sgml | 525 - etc/iproute2/ematch_map | 5 - etc/iproute2/rt_dsfield | 13 - etc/iproute2/rt_protos | 29 - etc/iproute2/rt_realms | 13 - etc/iproute2/rt_scopes | 11 - etc/iproute2/rt_tables | 11 - examples/README.cbq | 122 - examples/SYN-DoS.rate.limit | 49 - examples/cbq.init-v0.7.3 | 984 -- examples/cbqinit.eth1 | 76 - examples/dhcp-client-script | 446 - examples/diffserv/Edge1 | 68 - examples/diffserv/Edge2 | 87 - examples/diffserv/Edge31-ca-u32 | 170 - examples/diffserv/Edge31-cb-chains | 132 - examples/diffserv/Edge32-ca-u32 | 198 - examples/diffserv/Edge32-cb-chains | 144 - examples/diffserv/Edge32-cb-u32 | 145 - examples/diffserv/README | 98 - examples/diffserv/afcbq | 105 - examples/diffserv/ef-prio | 25 - examples/diffserv/efcbq | 31 - examples/diffserv/regression-testing | 125 - include/SNAPSHOT.h | 1 - include/ip6tables.h | 141 - include/iptables.h | 177 - include/iptables_common.h | 38 - include/libiptc/ipt_kernel_headers.h | 27 - include/libiptc/libip6tc.h | 154 - include/libiptc/libiptc.h | 166 - include/libnetlink.h | 57 - include/linux/gen_stats.h | 67 - include/linux/inet_diag.h | 122 - include/linux/ip_mp_alg.h | 22 - include/linux/netfilter_ipv4/ip_tables.h | 346 - include/linux/netlink.h | 134 - include/linux/pkt_cls.h | 428 - include/linux/pkt_sched.h | 469 - include/linux/rtnetlink.h | 906 -- include/linux/socket.h | 1 - include/linux/tc_act/tc_defact.h | 21 - include/linux/tc_act/tc_gact.h | 34 - include/linux/tc_act/tc_ipt.h | 21 - include/linux/tc_act/tc_mirred.h | 28 - include/linux/tc_act/tc_pedit.h | 36 - include/linux/tc_ematch/tc_em_cmp.h | 26 - include/linux/tc_ematch/tc_em_meta.h | 94 - include/linux/tc_ematch/tc_em_nbyte.h | 13 - include/linux/tcp.h | 161 - include/linux/xfrm.h | 311 - include/ll_map.h | 13 - include/net/tcp_states.h | 50 - include/rt_names.h | 30 - include/rtm_map.h | 10 - include/utils.h | 138 - ip.8 | 1809 --- ip/Makefile | 24 - ip/ifcfg | 145 - ip/ip.c | 237 - ip/ip_common.h | 35 - ip/ipaddress.c | 907 -- ip/iplink.c | 430 - ip/ipmaddr.c | 344 - ip/ipmonitor.c | 167 - ip/ipmroute.c | 205 - ip/ipneigh.c | 469 - ip/ipntable.c | 657 - ip/ipprefix.c | 106 - ip/iproute.c | 1431 --- ip/iprule.c | 375 - ip/iptunnel.c | 585 - ip/ipxfrm.c | 1185 -- ip/routef | 3 - ip/routel | 60 - ip/rtm_map.c | 116 - ip/rtmon.c | 178 - ip/rtpr | 4 - ip/xfrm.h | 143 - ip/xfrm_monitor.c | 218 - ip/xfrm_policy.c | 738 -- ip/xfrm_state.c | 950 -- iproute.spec | 43 +- lib/Makefile | 18 - lib/dnet_ntop.c | 98 - lib/dnet_pton.c | 71 - lib/inet_proto.c | 70 - lib/ipx_ntop.c | 71 - lib/ipx_pton.c | 107 - lib/libnetlink.c | 588 - lib/ll_addr.c | 94 - lib/ll_map.c | 172 - lib/ll_proto.c | 129 - lib/ll_types.c | 134 - lib/rt_names.c | 396 - lib/utils.c | 640 - man/man3/libnetlink.3 | 197 - man/man8/ip.8 | 1813 --- man/man8/tc-cbq-details.8 | 425 - man/man8/tc-cbq.8 | 353 - man/man8/tc-htb.8 | 150 - man/man8/tc-pbfifo.8 | 72 - man/man8/tc-pfifo.8 | 0 man/man8/tc-pfifo_fast.8 | 59 - man/man8/tc-prio.8 | 187 - man/man8/tc-red.8 | 131 - man/man8/tc-sfq.8 | 107 - man/man8/tc-tbf.8 | 138 - man/man8/tc.8 | 348 - misc/Makefile | 35 - misc/arpd.c | 847 -- misc/ifstat.c | 769 -- misc/lnstat.c | 337 - misc/lnstat.h | 43 - misc/lnstat_util.c | 329 - misc/netbug | 53 - misc/nstat.c | 621 - misc/rtacct.c | 628 - misc/ss.c | 2821 ----- misc/ssfilter.h | 21 - misc/ssfilter.y | 275 - netem/Makefile | 25 - netem/README.distribution | 97 - netem/experimental.dat | 13448 --------------------- netem/maketable.c | 232 - netem/normal.c | 51 - netem/pareto.c | 41 - netem/paretonormal.c | 82 - tc-cbq-details.8 | 425 - tc-cbq.8 | 353 - tc-htb.8 | 150 - tc-pbfifo.8 | 72 - tc-pfifo_fast.8 | 59 - tc-prio.8 | 187 - tc-red.8 | 131 - tc-sfq.8 | 107 - tc-tbf.8 | 138 - tc.8 | 348 - tc/Makefile | 89 - tc/README.last | 47 - tc/em_cmp.c | 188 - tc/em_meta.c | 550 - tc/em_nbyte.c | 144 - tc/em_u32.c | 178 - tc/emp_ematch.l | 145 - tc/emp_ematch.y | 101 - tc/f_basic.c | 146 - tc/f_fw.c | 140 - tc/f_route.c | 169 - tc/f_rsvp.c | 404 - tc/f_tcindex.c | 185 - tc/f_u32.c | 1084 -- tc/m_action.c | 608 - tc/m_ematch.c | 493 - tc/m_ematch.h | 179 - tc/m_estimator.c | 64 - tc/m_gact.c | 244 - tc/m_ipt.c | 596 - tc/m_mirred.c | 295 - tc/m_pedit.c | 606 - tc/m_pedit.h | 62 - tc/m_police.c | 359 - tc/p_icmp.c | 61 - tc/p_ip.c | 159 - tc/p_tcp.c | 38 - tc/p_udp.c | 38 - tc/q_atm.c | 260 - tc/q_cbq.c | 553 - tc/q_dsmark.c | 177 - tc/q_fifo.c | 98 - tc/q_gred.c | 312 - tc/q_hfsc.c | 406 - tc/q_htb.c | 330 - tc/q_ingress.c | 69 - tc/q_netem.c | 385 - tc/q_prio.c | 119 - tc/q_red.c | 219 - tc/q_sfq.c | 107 - tc/q_tbf.c | 264 - tc/tc.c | 313 - tc/tc_cbq.c | 57 - tc/tc_cbq.h | 9 - tc/tc_class.c | 322 - tc/tc_common.h | 11 - tc/tc_core.c | 89 - tc/tc_core.h | 19 - tc/tc_estimator.c | 44 - tc/tc_filter.c | 371 - tc/tc_qdisc.c | 323 - tc/tc_red.c | 97 - tc/tc_red.h | 8 - tc/tc_util.c | 519 - tc/tc_util.h | 84 - testsuite/Makefile | 45 - testsuite/configs/all-2.4 | 848 -- testsuite/configs/all-no-act | 1499 --- testsuite/configs/all-police-act | 1504 --- testsuite/iproute2/Makefile | 33 - testsuite/lib/generic.sh | 88 - testsuite/tests/cbq.t | 10 - testsuite/tests/cls-testbed.t | 68 - testsuite/tests/dsmark.t | 31 - testsuite/tests/policer | 13 - 228 files changed, 74 insertions(+), 72482 deletions(-) delete mode 100644 COPYING delete mode 100644 ChangeLog delete mode 100644 README delete mode 100644 README.decnet delete mode 100644 README.distribution delete mode 100644 README.iproute2+tc delete mode 100644 README.lnstat delete mode 100644 RELNOTES delete mode 100755 configure delete mode 100644 doc/Makefile delete mode 100644 doc/Plan delete mode 100644 doc/SNAPSHOT.tex delete mode 100644 doc/actions/actions-general delete mode 100644 doc/actions/dummy-README delete mode 100644 doc/actions/gact-usage delete mode 100644 doc/actions/mirred-usage delete mode 100644 doc/api-ip6-flowlabels.tex delete mode 100644 doc/arpd.sgml delete mode 100755 doc/do-psnup delete mode 100644 doc/ip-cref.tex delete mode 100644 doc/ip-tunnels.tex delete mode 100644 doc/nstat.sgml delete mode 100644 doc/preamble.tex delete mode 100644 doc/rtstat.sgml delete mode 100644 doc/ss.sgml delete mode 100644 etc/iproute2/ematch_map delete mode 100644 etc/iproute2/rt_dsfield delete mode 100644 etc/iproute2/rt_protos delete mode 100644 etc/iproute2/rt_realms delete mode 100644 etc/iproute2/rt_scopes delete mode 100644 etc/iproute2/rt_tables delete mode 100644 examples/README.cbq delete mode 100644 examples/SYN-DoS.rate.limit delete mode 100644 examples/cbq.init-v0.7.3 delete mode 100755 examples/cbqinit.eth1 delete mode 100755 examples/dhcp-client-script delete mode 100644 examples/diffserv/Edge1 delete mode 100644 examples/diffserv/Edge2 delete mode 100644 examples/diffserv/Edge31-ca-u32 delete mode 100644 examples/diffserv/Edge31-cb-chains delete mode 100644 examples/diffserv/Edge32-ca-u32 delete mode 100644 examples/diffserv/Edge32-cb-chains delete mode 100644 examples/diffserv/Edge32-cb-u32 delete mode 100644 examples/diffserv/README delete mode 100644 examples/diffserv/afcbq delete mode 100644 examples/diffserv/ef-prio delete mode 100644 examples/diffserv/efcbq delete mode 100644 examples/diffserv/regression-testing delete mode 100644 include/SNAPSHOT.h delete mode 100644 include/ip6tables.h delete mode 100644 include/iptables.h delete mode 100644 include/iptables_common.h delete mode 100644 include/libiptc/ipt_kernel_headers.h delete mode 100644 include/libiptc/libip6tc.h delete mode 100644 include/libiptc/libiptc.h delete mode 100644 include/libnetlink.h delete mode 100644 include/linux/gen_stats.h delete mode 100644 include/linux/inet_diag.h delete mode 100644 include/linux/ip_mp_alg.h delete mode 100644 include/linux/netfilter_ipv4/ip_tables.h delete mode 100644 include/linux/netlink.h delete mode 100644 include/linux/pkt_cls.h delete mode 100644 include/linux/pkt_sched.h delete mode 100644 include/linux/rtnetlink.h delete mode 100644 include/linux/socket.h delete mode 100644 include/linux/tc_act/tc_defact.h delete mode 100644 include/linux/tc_act/tc_gact.h delete mode 100644 include/linux/tc_act/tc_ipt.h delete mode 100644 include/linux/tc_act/tc_mirred.h delete mode 100644 include/linux/tc_act/tc_pedit.h delete mode 100644 include/linux/tc_ematch/tc_em_cmp.h delete mode 100644 include/linux/tc_ematch/tc_em_meta.h delete mode 100644 include/linux/tc_ematch/tc_em_nbyte.h delete mode 100644 include/linux/tcp.h delete mode 100644 include/linux/xfrm.h delete mode 100644 include/ll_map.h delete mode 100644 include/net/tcp_states.h delete mode 100644 include/rt_names.h delete mode 100644 include/rtm_map.h delete mode 100644 include/utils.h delete mode 100644 ip.8 delete mode 100644 ip/Makefile delete mode 100755 ip/ifcfg delete mode 100644 ip/ip.c delete mode 100644 ip/ip_common.h delete mode 100644 ip/ipaddress.c delete mode 100644 ip/iplink.c delete mode 100644 ip/ipmaddr.c delete mode 100644 ip/ipmonitor.c delete mode 100644 ip/ipmroute.c delete mode 100644 ip/ipneigh.c delete mode 100644 ip/ipntable.c delete mode 100644 ip/ipprefix.c delete mode 100644 ip/iproute.c delete mode 100644 ip/iprule.c delete mode 100644 ip/iptunnel.c delete mode 100644 ip/ipxfrm.c delete mode 100755 ip/routef delete mode 100755 ip/routel delete mode 100644 ip/rtm_map.c delete mode 100644 ip/rtmon.c delete mode 100755 ip/rtpr delete mode 100644 ip/xfrm.h delete mode 100644 ip/xfrm_monitor.c delete mode 100644 ip/xfrm_policy.c delete mode 100644 ip/xfrm_state.c delete mode 100644 lib/Makefile delete mode 100644 lib/dnet_ntop.c delete mode 100644 lib/dnet_pton.c delete mode 100644 lib/inet_proto.c delete mode 100644 lib/ipx_ntop.c delete mode 100644 lib/ipx_pton.c delete mode 100644 lib/libnetlink.c delete mode 100644 lib/ll_addr.c delete mode 100644 lib/ll_map.c delete mode 100644 lib/ll_proto.c delete mode 100644 lib/ll_types.c delete mode 100644 lib/rt_names.c delete mode 100644 lib/utils.c delete mode 100644 man/man3/libnetlink.3 delete mode 100644 man/man8/ip.8 delete mode 100644 man/man8/tc-cbq-details.8 delete mode 100644 man/man8/tc-cbq.8 delete mode 100644 man/man8/tc-htb.8 delete mode 100644 man/man8/tc-pbfifo.8 delete mode 100644 man/man8/tc-pfifo.8 delete mode 100644 man/man8/tc-pfifo_fast.8 delete mode 100644 man/man8/tc-prio.8 delete mode 100644 man/man8/tc-red.8 delete mode 100644 man/man8/tc-sfq.8 delete mode 100644 man/man8/tc-tbf.8 delete mode 100644 man/man8/tc.8 delete mode 100644 misc/Makefile delete mode 100644 misc/arpd.c delete mode 100644 misc/ifstat.c delete mode 100644 misc/lnstat.c delete mode 100644 misc/lnstat.h delete mode 100644 misc/lnstat_util.c delete mode 100755 misc/netbug delete mode 100644 misc/nstat.c delete mode 100644 misc/rtacct.c delete mode 100644 misc/ss.c delete mode 100644 misc/ssfilter.h delete mode 100644 misc/ssfilter.y delete mode 100644 netem/Makefile delete mode 100644 netem/README.distribution delete mode 100644 netem/experimental.dat delete mode 100644 netem/maketable.c delete mode 100644 netem/normal.c delete mode 100644 netem/pareto.c delete mode 100644 netem/paretonormal.c delete mode 100644 tc-cbq-details.8 delete mode 100644 tc-cbq.8 delete mode 100644 tc-htb.8 delete mode 100644 tc-pbfifo.8 delete mode 100644 tc-pfifo_fast.8 delete mode 100644 tc-prio.8 delete mode 100644 tc-red.8 delete mode 100644 tc-sfq.8 delete mode 100644 tc-tbf.8 delete mode 100644 tc.8 delete mode 100644 tc/Makefile delete mode 100644 tc/README.last delete mode 100644 tc/em_cmp.c delete mode 100644 tc/em_meta.c delete mode 100644 tc/em_nbyte.c delete mode 100644 tc/em_u32.c delete mode 100644 tc/emp_ematch.l delete mode 100644 tc/emp_ematch.y delete mode 100644 tc/f_basic.c delete mode 100644 tc/f_fw.c delete mode 100644 tc/f_route.c delete mode 100644 tc/f_rsvp.c delete mode 100644 tc/f_tcindex.c delete mode 100644 tc/f_u32.c delete mode 100644 tc/m_action.c delete mode 100644 tc/m_ematch.c delete mode 100644 tc/m_ematch.h delete mode 100644 tc/m_estimator.c delete mode 100644 tc/m_gact.c delete mode 100644 tc/m_ipt.c delete mode 100644 tc/m_mirred.c delete mode 100644 tc/m_pedit.c delete mode 100644 tc/m_pedit.h delete mode 100644 tc/m_police.c delete mode 100644 tc/p_icmp.c delete mode 100644 tc/p_ip.c delete mode 100644 tc/p_tcp.c delete mode 100644 tc/p_udp.c delete mode 100644 tc/q_atm.c delete mode 100644 tc/q_cbq.c delete mode 100644 tc/q_dsmark.c delete mode 100644 tc/q_fifo.c delete mode 100644 tc/q_gred.c delete mode 100644 tc/q_hfsc.c delete mode 100644 tc/q_htb.c delete mode 100644 tc/q_ingress.c delete mode 100644 tc/q_netem.c delete mode 100644 tc/q_prio.c delete mode 100644 tc/q_red.c delete mode 100644 tc/q_sfq.c delete mode 100644 tc/q_tbf.c delete mode 100644 tc/tc.c delete mode 100644 tc/tc_cbq.c delete mode 100644 tc/tc_cbq.h delete mode 100644 tc/tc_class.c delete mode 100644 tc/tc_common.h delete mode 100644 tc/tc_core.c delete mode 100644 tc/tc_core.h delete mode 100644 tc/tc_estimator.c delete mode 100644 tc/tc_filter.c delete mode 100644 tc/tc_qdisc.c delete mode 100644 tc/tc_red.c delete mode 100644 tc/tc_red.h delete mode 100644 tc/tc_util.c delete mode 100644 tc/tc_util.h delete mode 100644 testsuite/Makefile delete mode 100644 testsuite/configs/all-2.4 delete mode 100644 testsuite/configs/all-no-act delete mode 100644 testsuite/configs/all-police-act delete mode 100644 testsuite/iproute2/Makefile delete mode 100644 testsuite/lib/generic.sh delete mode 100644 testsuite/tests/cbq.t delete mode 100644 testsuite/tests/cls-testbed.t delete mode 100644 testsuite/tests/dsmark.t delete mode 100644 testsuite/tests/policer diff --git a/COPYING b/COPYING deleted file mode 100644 index 2b7b643..0000000 --- a/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index 3590a64..0000000 --- a/ChangeLog +++ /dev/null @@ -1,563 +0,0 @@ -2006-03-21 Stephen Hemminger - - * Back out the 2.4 utsname patch - -2006-03-21 James Lentini - - * Increase size of hw address allowed for ip neigh to allow - for IB. - -2006-03-14 Russell Stuart - - * Fix missing memset in tc sample - * Fixes for tc hash samples - * Add sample divisor - -2006-03-10 Alpt - - * Add more rt_proto values - -2006-03-10 Dale Sedivec - - * Warn when using "handle" instead of "classid" with "tc class" - -2006-03-10 Jean Tourrilhes - - * Fix endless loop in netlink error handling - - -2006-03-10 Stephen Hemminger - - * Change default lnstat count to 1 - * Update to 2.6.16 headers - * Add fake version of include/linux/socket.h to fix warnings - -2006-01-12 Patrick McHardy - - * Handle DCCP in ipxfrm.c to allow using port numbers in the selector. - -2006-01-10 Masahide NAKAMURA - - * Add ip link ntable - -2006-01-10 Stephen Hemminger - - * Update headers to santized kernel 2.6.15 - * Fix ipv6 priority option in u32 - -2006-01-03 Alpt - - * Ip man page addition - -2006-01-03 Jamal Hadi Salim - - * Documentation for ifb - -2005-12-09 Stephen Hemminger - - * Add corrupt feature to netem - -2005-12-02 Stephen Hemminger - - * Backout ambigious ip command matches - -2005-11-22 Stephen Hemminger - - * Handle ambigious ip command matches - -2005-11-22 Patrick McHardy - - * Add back ip command aliases - -2005-11-07 Masahide NAKAMURA - - * Updating for 2.6.14 - - Show UPD{SA,POLICY} message information from kernel instead of error - - Add lengh check of deleting message from kernel - - Use macro for struct xfrm_user{sa,policy}_id - - * Minor fix: - - Add fflush at the end of normal dump - -2005-11-01 Jamal Hadi Salim - - * Fix handling of XFRM monitor and state - -2005-11-01 Stephen Hemminger - - * Fix ip commnad shortcuts - -2005-10-12 Stephen Hemminger - - * Add more CBQ examples from Fedora Core - * Fix buffer overrun in iproute because of bits vs. bytes confusion - -2005-10-12 Jamal Hadi Salim - - * Fix ip rule flush, need to reopen rtnl - -2005-10-07 Stephen Hemminger - - * Reenable ip mroute - -2005-10-07 Mike Frysinger - - * Handle pfifo_fast that has no qopt without segfaulting - -2005-10-05 Mads Martin Joergensen - - * Trivial netem ccopts - -2005-10-04 Jerome Borsboom - - * Fix regression in ip addr (libnetlink) handling - -2005-09-21 Stephen Hemminger - - * Fix uninitialized memory and leaks with valgrind - Reported by Redhat - -2005-09-01 Mike Frysinger - - * Fix build issues with netem tables (parallel make and HOSTCC) - -2005-09-01 Stephen Hemminger - - * Integrate support for DCCP into 'ss' (from acme) - * Add -batch option to ip. - * Update to 2.6.14 headers - -2005-09-01 Eric Dumazet - - * Fix lnstat : First column should not be summed - -2005-08-16 Stephen Hemminger - - * Limit ip route flush to 10 rounds. - * Cleanup ip rule flush error message - -2005-08-08 Stephen Hemminger - - * Update to 2.6.13+ kernel headers - * Fix array overrun in paretonormal - * Fix ematch to not include dropped fields from skb. - -2005-07-14 Thomas Graf - - * Make ematch bison/lex build with common flex - -2005-07-10 Stephen Hemminger - - * Fix Gcc 4.0 build warnings signed/unsigned - -2005-06-23 Jamal Hadi Salim - - * Fix for options process with ipt - -2005-06-23 Thomas Graf - - * Add extended matches (nbyte, cmp, u32, meta) - * Add basic classifier - * Fix clean/distclean makefile targets - * update local header file copies - * IPv4 multipath algorithm selection support - * cscope Makefile target - * Fix off-by-one while generating argument vector - in batched mode. - * Assume stdin if no argument is given to -batch - -2005-06-22 Stephen Hemminger - - * Update include files to 2.6.12 - * Add ss support for TCP_CONG - -2005-06-13 Steven Whitehouse - - * Decnet doc's update - -2005-06-07 Stephen Hemminger - - * Fix 'ip link' map to handle case where device gets autoloaded - by using if_nametoindex as fallback - * Device indices are unsigned not int. - -2005-06-07 Masahide NAKAMURA - - * [ip] show timestamp when using '-t' option. - * [ip] remove duplicated code for expired message of xfrm. - * [ip] add "deleteall" command for xfrm; - "flush" uses kernel's flush interface and - "deleteall" uses legacy iproute2's flush feature like - getting-and-deleting-for-each. - -2005-03-30 Stephen Hemminger - - * include/linux/netfilter_ipv4/ip_tables.h dont include compiler.h - because it isn't needed and not on all systems - * Update rtnetlink.h and pkt_cls.h to be stripped versions - of headers from 2.6.12-rc1 - -2005-03-30 Jamal Hadi Salim - - * Proper verison of iptables headers (from 1.3.1) - * Set revision file in m_ipt - * Fix action_util naming in mirred - * don't call ll_init_map in mirred - -2005-03-19 Thomas Graf - - * Warn about wildcard deletions and provide IFA_ADDRESS upon - deletions to enforce prefix length validation for IPv4. - * Fix netlink message alignment when the last routing attribute added - has a data length not aligned to RTA_ALIGNTO. - -2005-03-30 Masahide NAKAMURA - - * ipv6 xfrm allocspi and monitor support. - -2005-03-29 Stephen Hemminger - - * switch to stack for netem tables - -2005-03-18 Stephen Hemminger - - * add -force option to batch mode - * handle midline comments in batch mode - * sum per cpu fields in lnstat correctly - -2005-03-14 Stephen Hemminger - - * cleanup batch mode, allow continuation, comments etc. - * recode reuse of netlink socket - -2005-03-14 Boian Bonev - - * enhancement to batch mode. - it does not exit on error, just report it - tc reuses the already open netlink socket for subsequent command(s) - -2005-03-14 Thomas Graf - - * ip link command - print NO-CARRIER flag if there is no carrier and the link is up. - -2005-03-14 Patrick McHardy - - * bug: Use USER_HZ where necessary - -2005-03-10 Jamal Hadi Salim - - * Fix bug with register_target - -2005-03-10 Stephen Hemminger - - * fix pkt_cls.h to have tc_u32_mark - * update include files to be stripped versions of 2.6.11 - * add documentation about netem distributions [from nistnet] - * turn off nup in document make [from FC3] - * don't build with extra debug info (-g) [from FC3] - -2005-03-10 Nix - - * make man3 directory - -2005-03-10 Pasi - - * add ESP-in-UDP encapsulation - -2005-03-10 Thomas Graf - * [NETEM] Fix off by one - * update local header file copies - * [NEIGH] print number of probes done so far (statistics mode only) - -2005-03-10 Herbert Xu - * Trivial typo in ip help - -2005-02-09 Stephen Hemminger - - * netem distribution data reorganization - -2005-02-09 Roland Dreier - - * ip over infiniband address display - -2005-02-09 Jim Gifford - - * make install fix for ip/ - -2005-02-07 Mads Martin Joergensen - - * Don't mix address families when flushing - -2005-02-07 Stephen Hemminger - - * Validate classid is not too large to cause loss of bits. - -2005-02-07 Jean-Marc Ranger - - * need to call getline() with null for first usage - * don't overwrite const arg - -2005-02-07 Stephen Hemminger - - * Add experimental distribution - -2005-01-18 Yun Mao - - * typo in ss - -2005-01-18 Thomas Graf - - * tc pedit/action cleanups - * add addraw_l - * rtattr_parse cleanups - -2005-01-17 Jamal Hadi Salim - - * typo in m_mirred - * add support for pedit - -2005-01-13 Jim Gifford - - * Fix allocation size error in nomal and paretonormal generation - programs. - -2005-01-12 Masahide Nakamura - - * ipmonitor shows IPv6 prefix list notification - * update to iproute2 xfrm for ipv6 - -2005-01-12 Stephen Hemminger - - * Fix compile warnings when building 64bit system since - u64 is unsigned long, but format is %llu - -2005-01-12 "Catalin(ux aka Dino) BOIE" - - * Add the possibility to use fwmark in u32 filters - -2005-01-12 Andi Kleen - - * Add netlink manual page - -2004-10-20 Stephen Hemminger - - * Add warning about "ip route nat" no longer supported - -2005-01-12 Thomas Graf - - * Tc testsuite - -2005-01-12 Jamal Hadi Salim - - * Add iptables tc support. This meant borrowing headers - from iptables *ugh* - -2004-12-08 Jamal Hadi Salim - - * Add mirror and redirect actions - -2004-10-20 Stephen Hemminger - - * Don't include since then we get dependant on - kernel headers on host machine - * Minor fix for building on old machine without IPPROTO_SCTP - -2004-10-19 Harald Welte - - * Replace rtstat (and ctstat) with new lnstat - -2004-10-19 Mads Martin Joergensen - - * Ip is using the wrong structure in ipaddress.c when showing stats - * Make sure no buffer overflow in nstat - -2004-10-19 Michal - - * fix scaling in print_rates (for bits) - -2004-09-28 Stephen Hemminger - - * fix build problems with arpd and pthread - * add pkt_sched.h - -2004-09-28 Mike Frysinger - - * make man8 directory - * install ifcfg and rtpr scripts - -2004-09-28 Andreas Haumer - - * make install symlink fix. - -2004-09-28 Masahide Nakamura - - * ICMP/ICMPv6's type and code in IPsec selector. - * fixes `ip xfrm`'s algorithm key when using hexadecimal - * support 'ip xfrm' protocol types - * flush message types for XFRM's policy/state - - -2004-09-01 Stephen Hemminger - - * Fix ip command to not crash when interface name is too long. - always use strncpy(.., IFNAMSIZ) - -2004-08-31 Stephen Hemminger - - * Add gact documentation from jamal - * Chang more arguments to rtnetlink API const - * Drop dead queuing disciplines - * Handle qdisc without xstats in core rather than - putting stub's everywhere - * Add requeue to tc_stats and handle new/old ABI issues - -2004-08-30 Stephen Hemminger - - * Make clean and install changes for man pages - * Patch from jamal to support gact - * Add support for loading distributions to netem - - -2004-08-23 Stephen Hemminger - - * Update from jamal for all the parts that got broken in the - last classification patch. - * Hfsc/sc patch from patrick - -2004-08-13 Stephen Hemminger - - * Add jamal's tc extensions for classification - * Get rid of old Patches/ directory for tcp_diag module - * Make get_rate table based. - -2004-08-11 Stephen Hemminger - - * Add xfrm message formatting from - Masahide Nakamura - -2004-08-09 Stephen Hemminger - - * Fix netem scheduler to handle case where psched us != real us - - * Remove configuration for everything that can depend on - extracted kernel headers - * Add kernel headers required to include/linux - -2004-08-04 Stephen Hemminger - - * Get rid of old tcp_diag module, it is part of kernel. - - * Add some kernel include files back (netlink, tcp_diag, pkt_sched) - -2004-07-30 Stephen Hemminger - - * Make ip xfrm stuff config option since it doesn't exist on 2.4 - - * HFSC doesn't exist on older 2.4 kernels so make it configurable - - * HTB API changed and won't build with mismatched version. - Rather than sticking user with a build error, just don't - build it in on mismatch. - - * Change configure script to make sure netem is the correct - version. I changed the structure def. a couple of times before - settling on the final API - -2004-07-16 Stephen Hemminger - - * Add htb mpu support - http://luxik.cdi.cz/~devik/qos/htb/v3/htb_tc_overhead.diff - * Three small xfrm updates - -2004-07-07 Stephen Hemminger - - * Fix if_ether.h to fix arpd build - * Add hfsc scheduler support - * Add ip xfrm support - * Add add jitter (instead of rate) to netem scheduler - -2004-07-02 Stephen Hemminger - - * use compile to test for ATM libraries - * put TC layered scheduler hooks in /usr/lib/tc as shared lib - before it looked in standard search path (/lib;/usr/lib;...) - which seems out of place. - * build netem as shared library (more for testing/example) - * build ATM as shared library since libatm may be on build - machine but not on deployment machine - * fix make install to not install SCCS directories - -2004-07-01 Stephen Hemminger - - * add more link options to ip command (from Mark Smith - * add rate and duplicate arguments to tc command - * add -iec flag for tc printout - * rename delay scheduler to netem - -2004-06-25 Stephen Hemminger - - * Add loss parameter to delay - * Rename delay qdisc to netsim - * Add autoconfiguration by building a Config file - and using it. - -2004-06-09 Stephen Hemminger - - * Report rates in K=1000 (requested by several people) - * Add GNU long style options - * For HTB use get_hz to pick up value of system HZ at runtime - * Delete unused funcs. - -2004-06-08 Stephen Hemminger - - * Cleanup ss - - use const char and local functions where possible - * Add man pages from SuSe - * SuSE patches - - path to db4.1 - - don't hardcode path to /tmp in ifstat - Alternat fix: was to use TMPDIR - - handle non-root user calling ip route flush going into - an infinite loop. - Alternate fix: was to timeout if route table doesn't empty. - * Try and get rid of dependency on kernel include files - Get rid of having private glibc-include headers - -2004-06-07 Stephen Hemminger - - * Import patches that make sense from Fedora Core 2 - - iproute2-2.4.7-hex - print fwmark in hex - - iproute2-2.4.7-netlink - handle getting right netlink mesg back - - iproute2-2.4.7-htb3-tc - add HTB scheduler - - iproute2-2.4.7-default - add entry default to rttable - -2004-06-04 Stephen Hemminger - - * Add support for vegas info to ss - -2004-06-02 Stephen Hemminger - - * Use const char in utility routines where appropriate - * Rearrange include files so can build with standard headers - * For "tc qdisc ls" see the default queuing discpline "pfifo_fast" - and understand it - * Get rid of private defintions of network headers which existed - only to handle old glibc - -2004-04-15 Stephen Hemminger - - * Add the delay (network simulation scheduler) - -2004-04-15 Stephen Hemminger - - * Starting point baseline based on iproute2-2.4.7-ss020116-try - diff --git a/Makefile b/Makefile index ac58cd9..f38255e 100644 --- a/Makefile +++ b/Makefile @@ -1,72 +1,62 @@ -DESTDIR= -SBINDIR=/usr/sbin -CONFDIR=/etc/iproute2 -DOCDIR=/usr/share/doc/iproute2 -MANDIR=/usr/share/man - -# Path to db_185.h include -DBM_INCLUDE:=/usr/include - -DEFINES= -DRESOLVE_HOSTNAMES - -#options if you have a bind>=4.9.4 libresolv (or, maybe, glibc) -LDLIBS=-lresolv -ADDLIB= - -#options for decnet -ADDLIB+=dnet_ntop.o dnet_pton.o - -#options for ipx -ADDLIB+=ipx_ntop.o ipx_pton.o - -CC = gcc -HOSTCC = gcc -CCOPTS = -D_GNU_SOURCE -O2 -Wstrict-prototypes -Wall -CFLAGS = $(CCOPTS) -I../include $(DEFINES) -YACCFLAGS = -d -t -v - -LDLIBS += -L../lib -lnetlink -lutil - -SUBDIRS=lib ip tc misc netem - -LIBNETLINK=../lib/libnetlink.a ../lib/libutil.a - -all: Config - @for i in $(SUBDIRS); \ - do $(MAKE) $(MFLAGS) -C $$i; done - -Config: - sh configure $(KERNEL_INCLUDE) - -install: all - install -m 0755 -d $(DESTDIR)$(SBINDIR) - install -m 0755 -d $(DESTDIR)$(CONFDIR) - install -m 0755 -d $(DESTDIR)$(DOCDIR)/examples - install -m 0755 -d $(DESTDIR)$(DOCDIR)/examples/diffserv - install -m 0644 README.iproute2+tc $(shell find examples -maxdepth 1 -type f) \ - $(DESTDIR)$(DOCDIR)/examples - install -m 0644 $(shell find examples/diffserv -maxdepth 1 -type f) \ - $(DESTDIR)$(DOCDIR)/examples/diffserv - @for i in $(SUBDIRS) doc; do $(MAKE) -C $$i install; done - install -m 0644 $(shell find etc/iproute2 -maxdepth 1 -type f) $(DESTDIR)$(CONFDIR) - install -m 0755 -d $(DESTDIR)$(MANDIR)/man8 - install -m 0644 $(shell find man/man8 -maxdepth 1 -type f) $(DESTDIR)$(MANDIR)/man8 - ln -sf tc-pbfifo.8 $(DESTDIR)$(MANDIR)/man8/tc-bfifo.8 - ln -sf tc-pbfifo.8 $(DESTDIR)$(MANDIR)/man8/tc-pfifo.8 - install -m 0755 -d $(DESTDIR)$(MANDIR)/man3 - install -m 0644 $(shell find man/man3 -maxdepth 1 -type f) $(DESTDIR)$(MANDIR)/man3 +# $Id$ +# $URL$ +# +WEBFETCH := wget +SHA1SUM := sha1sum + +ALL += iproute2 +iproute2-URL := http://devresources.linuxfoundation.org/dev/iproute2/download/iproute2-2.6.33.tar.bz2 +iproute2-SHA1SUM := 09d12790458b1d9e4fbd72d962304ac81530c4da +iproute2 := $(notdir $(iproute2-URL)) + +all: $(ALL) +.PHONY: all + +############################## +define download_target +$(1): $($(1)) +.PHONY: $($(1)) +$($(1)): + @if [ ! -e "$($(1))" ] ; then echo "$(WEBFETCH) $($(1)-URL)" ; $(WEBFETCH) $($(1)-URL) ; fi + @if [ ! -e "$($(1))" ] ; then echo "Could not download source file: $($(1)) does not exist" ; exit 1 ; fi + @if test "$$$$($(SHA1SUM) $($(1)) | awk '{print $$$$1}')" != "$($(1)-SHA1SUM)" ; then \ + echo "sha1sum of the downloaded $($(1)) does not match the one from 'Makefile'" ; \ + echo "Local copy: $$$$($(SHA1SUM) $($(1)))" ; \ + echo "In Makefile: $($(1)-SHA1SUM)" ; \ + false ; \ + else \ + ls -l $($(1)) ; \ + fi +endef + +$(eval $(call download_target,iproute2)) + +sources: $(ALL) +.PHONY: sources + +#################### +# default - overridden by the build +SPECFILE = iproute.spec + +PWD=$(shell pwd) +PREPARCH ?= noarch +RPMDIRDEFS = --define "_sourcedir $(PWD)" --define "_builddir $(PWD)" --define "_srcrpmdir $(PWD)" --define "_rpmdir $(PWD)" +trees: sources + rpmbuild $(RPMDIRDEFS) $(RPMDEFS) --nodeps -bp --target $(PREPARCH) $(SPECFILE) + +srpm: sources + rpmbuild $(RPMDIRDEFS) $(RPMDEFS) --nodeps -bs $(SPECFILE) + +TARGET ?= $(shell uname -m) +rpm: sources + rpmbuild $(RPMDIRDEFS) $(RPMDEFS) --nodeps --target $(TARGET) -bb $(SPECFILE) clean: - rm -f cscope.* - @for i in $(SUBDIRS) doc; \ - do $(MAKE) $(MFLAGS) -C $$i clean; done - -clobber: clean - rm -f Config - -distclean: clobber - -cscope: - cscope -b -q -R -Iinclude -sip -slib -smisc -snetem -stc - -.EXPORT_ALL_VARIABLES: + rm -f *.rpm *.tgz *.bz2 *.gz + +++%: varname=$(subst +,,$@) +++%: + @echo "$(varname)=$($(varname))" ++%: varname=$(subst +,,$@) ++%: + @echo "$($(varname))" diff --git a/README b/README deleted file mode 100644 index d86f605..0000000 --- a/README +++ /dev/null @@ -1,34 +0,0 @@ -Primary site is: - http://developer.osdl.org/dev/iproute2 - -Original FTP site is: - ftp://ftp.inr.ac.ru/ip-routing/ - -How to compile this. --------------------- -1. Look at start of Makefile and set correct values for: - -KERNEL_INCLUDE should point to correct linux kernel include directory. -Default (/usr/src/linux/include) is right as rule. - -DBM_INCLUDE points to the directory with db_185.h which -is the include file used by arpd to get to the old format Berkely -database routines. Often this is in the db-devel package. - -2. make - -The makefile will automatically build a file Config which -contains whether or not ATM is available, etc. - -3. To make documentation, cd to doc/ directory , then - look at start of Makefile and set correct values for - PAGESIZE=a4 , ie: a4 , letter ... (string) - PAGESPERPAGE=2 , ie: 1 , 2 ... (numeric) - and make there. It assumes, that latex, dvips and psnup - are in your path. - -Stephen Hemminger -shemminger@osdl.org - -Alexey Kuznetsov -kuznet@ms2.inr.ac.ru diff --git a/README.decnet b/README.decnet deleted file mode 100644 index 4300f90..0000000 --- a/README.decnet +++ /dev/null @@ -1,33 +0,0 @@ - -Here are a few quick points about DECnet support... - - o iproute2 is the tool of choice for configuring the DECnet support for - Linux. For many features, it is the only tool which can be used to - configure them. - - o No name resolution is available as yet, all addresses must be - entered numerically. - - o Remember to set the hardware address of the interface using: - - ip link set ethX address xx:xx:xx:xx:xx:xx - (where xx:xx:xx:xx:xx:xx is the MAC address for your DECnet node - address) - - if your Ethernet card won't listen to more than one unicast - mac address at once. If the Linux DECnet stack doesn't talk to - any other DECnet nodes, then check this with tcpdump and if its - a problem, change the mac address (but do this _before_ starting - any other network protocol on the interface) - - o Whilst you can use ip addr add to add more than one DECnet address to an - interface, don't expect addresses which are not the same as the - kernels node address to work properly with 2.4 kernels. This should - be fine with 2.6 kernels as the routing code has been extensively - modified and improved. - - o The DECnet support is currently self contained. It does not depend on - the libdnet library. - -Steve Whitehouse - diff --git a/README.distribution b/README.distribution deleted file mode 100644 index fe78fb4..0000000 --- a/README.distribution +++ /dev/null @@ -1,95 +0,0 @@ -I. About the distribution tables - -The table used for "synthesizing" the distribution is essentially a scaled, -translated, inverse to the cumulative distribution function. - -Here's how to think about it: Let F() be the cumulative distribution -function for a probability distribution X. We'll assume we've scaled -things so that X has mean 0 and standard deviation 1, though that's not -so important here. Then: - - F(x) = P(X <= x) = \int_{-inf}^x f - -where f is the probability density function. - -F is monotonically increasing, so has an inverse function G, with range -0 to 1. Here, G(t) = the x such that P(X <= x) = t. (In general, G may -have singularities if X has point masses, i.e., points x such that -P(X = x) > 0.) - -Now we create a tabular representation of G as follows: Choose some table -size N, and for the ith entry, put in G(i/N). Let's call this table T. - -The claim now is, I can create a (discrete) random variable Y whose -distribution has the same approximate "shape" as X, simply by letting -Y = T(U), where U is a discrete uniform random variable with range 1 to N. -To see this, it's enough to show that Y's cumulative distribution function, -(let's call it H), is a discrete approximation to F. But - - H(x) = P(Y <= x) - = (# of entries in T <= x) / N -- as Y chosen uniformly from T - = i/N, where i is the largest integer such that G(i/N) <= x - = i/N, where i is the largest integer such that i/N <= F(x) - -- since G and F are inverse functions (and F is - increasing) - = floor(N*F(x))/N - -as desired. - -II. How to create distribution tables (in theory) - -How can we create this table in practice? In some cases, F may have a -simple expression which allows evaluating its inverse directly. The -pareto distribution is one example of this. In other cases, and -especially for matching an experimentally observed distribution, it's -easiest simply to create a table for F and "invert" it. Here, we give -a concrete example, namely how the new "experimental" distribution was -created. - -1. Collect enough data points to characterize the distribution. Here, I -collected 25,000 "ping" roundtrip times to a "distant" point (time.nist.gov). -That's far more data than is really necessary, but it was fairly painless to -collect it, so... - -2. Normalize the data so that it has mean 0 and standard deviation 1. - -3. Determine the cumulative distribution. The code I wrote creates a table -covering the range -10 to +10, with granularity .00005. Obviously, this -is absurdly over-precise, but since it's a one-time only computation, I -figured it hardly mattered. - -4. Invert the table: for each table entry F(x) = y, make the y*TABLESIZE -(here, 4096) entry be x*TABLEFACTOR (here, 8192). This creates a table -for the ("normalized") inverse of size TABLESIZE, covering its domain 0 -to 1 with granularity 1/TABLESIZE. Note that even with the granularity -used in creating the table for F, it's possible not all the entries in -the table for G will be filled in. So, make a pass through the -inverse's table, filling in any missing entries by linear interpolation. - -III. How to create distribution tables (in practice) - -If you want to do all this yourself, I've provided several tools to help: - -1. maketable does the steps 2-4 above, and then generates the appropriate -header file. So if you have your own time distribution, you can generate -the header simply by: - - maketable < time.values > header.h - -2. As explained in the other README file, the somewhat sleazy way I have -of generating correlated values needs correction. You can generate your -own correction tables by compiling makesigtable and makemutable with -your header file. Check the Makefile to see how this is done. - -3. Warning: maketable, makesigtable and especially makemutable do -enormous amounts of floating point arithmetic. Don't try running -these on an old 486. (NIST Net itself will run fine on such a -system, since in operation, it just needs to do a few simple integral -calculations. But getting there takes some work.) - -4. The tables produced are all normalized for mean 0 and standard -deviation 1. How do you know what values to use for real? Here, I've -provided a simple "stats" utility. Give it a series of floating point -values, and it will return their mean (mu), standard deviation (sigma), -and correlation coefficient (rho). You can then plug these values -directly into NIST Net. diff --git a/README.iproute2+tc b/README.iproute2+tc deleted file mode 100644 index edd79c0..0000000 --- a/README.iproute2+tc +++ /dev/null @@ -1,119 +0,0 @@ -iproute2+tc* - -It's the first release of Linux traffic control engine. - - -NOTES. -* csz scheduler is inoperational at the moment, and probably - never will be repaired but replaced with h-pfq scheduler. -* To use "fw" classifier you will need ipfwchains patch. -* No manual available. Ask me, if you have problems (only try to guess - answer yourself at first 8)). - - -Micro-manual how to start it the first time -------------------------------------------- - -A. Attach CBQ to eth1: - -tc qdisc add dev eth1 root handle 1: cbq bandwidth 10Mbit allot 1514 cell 8 \ -avpkt 1000 mpu 64 - -B. Add root class: - -tc class add dev eth1 parent 1:0 classid 1:1 cbq bandwidth 10Mbit rate 10Mbit \ -allot 1514 cell 8 weight 1Mbit prio 8 maxburst 20 avpkt 1000 - -C. Add default interactive class: - -tc class add dev eth1 parent 1:1 classid 1:2 cbq bandwidth 10Mbit rate 1Mbit \ -allot 1514 cell 8 weight 100Kbit prio 3 maxburst 20 avpkt 1000 split 1:0 \ -defmap c0 - -D. Add default class: - -tc class add dev eth1 parent 1:1 classid 1:3 cbq bandwidth 10Mbit rate 8Mbit \ -allot 1514 cell 8 weight 800Kbit prio 7 maxburst 20 avpkt 1000 split 1:0 \ -defmap 3f - -etc. etc. etc. Well, it is enough to start 8) The rest can be guessed 8) -Look also at more elaborated example, ready to start rsvpd, -in rsvp/cbqinit.eth1. - - -Terminology and advices about setting CBQ parameters may be found in Sally Floyd -papers. - - -Pairs X:Y are class handles, X:0 are qdisc heandles. -weight should be proportional to rate for leaf classes -(I choosed it ten times less, but it is not necessary) - -defmap is bitmap of logical priorities served by this class. - -E. Another qdiscs are simpler. F.e. let's join TBF on class 1:2 - -tc qdisc add dev eth1 parent 1:2 tbf rate 64Kbit buffer 5Kb/8 limit 10Kb - -F. Look at all that we created: - -tc qdisc ls dev eth1 -tc class ls dev eth1 - -G. Install "route" classifier on root of cbq and map destination from realm -1 to class 1:2 - -tc filter add dev eth1 parent 1:0 protocol ip prio 100 route to 1 classid 1:2 - -H. Assign routes to 10.11.12.0/24 to realm 1 - -ip route add 10.11.12.0/24 dev eth1 via whatever realm 1 - -etc. The same thing can be made with rules. -I still did not test ipchains, but they should work too. - -Setup of rsvp and u32 classifiers is more hairy. -If you read RSVP specs, you will understand how rsvp classifier -works easily. What's about u32... That's example: - - - -#! /bin/sh - -TC=/home/root/tc - -# Setup classifier root on eth1 root (it is cbq) -$TC filter add dev eth1 parent 1:0 prio 5 protocol ip u32 - -# Create hash table of 256 slots with ID 1: -$TC filter add dev eth1 parent 1:0 prio 5 handle 1: u32 divisor 256 - -# Add to 6th slot of hash table rule to select tcp/telnet to 193.233.7.75 -# direct it to class 1:4 and prescribe to fall to best effort, -# if traffic violate TBF (32kbit,5K) -$TC filter add dev eth1 parent 1:0 prio 5 u32 ht 1:6: \ - match ip dst 193.233.7.75 \ - match tcp dst 0x17 0xffff \ - flowid 1:4 \ - police rate 32kbit buffer 5kb/8 mpu 64 mtu 1514 index 1 - -# Add to 1th slot of hash table rule to select icmp to 193.233.7.75 -# direct it to class 1:4 and prescribe to fall to best effort, -# if traffic violate TBF (10kbit,5K) -$TC filter add dev eth1 parent 1:0 prio 5 u32 ht 1:: \ - sample ip protocol 1 0xff \ - match ip dst 193.233.7.75 \ - flowid 1:4 \ - police rate 10kbit buffer 5kb/8 mpu 64 mtu 1514 index 2 - -# Lookup hash table, if it is not fragmented frame -# Use protocol as hash key -$TC filter add dev eth1 parent 1:0 prio 5 handle ::1 u32 ht 800:: \ - match ip nofrag \ - offset mask 0x0F00 shift 6 \ - hashkey mask 0x00ff0000 at 8 \ - link 1: - - -Alexey Kuznetsov -kuznet@ms2.inr.ac.ru diff --git a/README.lnstat b/README.lnstat deleted file mode 100644 index 057925f..0000000 --- a/README.lnstat +++ /dev/null @@ -1,81 +0,0 @@ -lnstat - linux networking statistics -(C) 2004 Harald Welte , various useful fixups: compilation - with old kernels, cross-compiling, "all" == "any" in prefix spec. - * Collected from my disk, cleaned and packed to directory iproute2/misc/ - several utilities: ss, nstat, ifstat, rtacct, arpd and module tcp_diag. - Writing some docs. me. - * prepared patchlet for pidentd to use tcp_diag. - * David Miller: 64bit (and even worse 64bit kernel/32 bit user :-) fixes - to above. tcp_diag is merged to main tree. - * Alexandr D. Kanevskiy : various flaws in ss - * Alexandr D. Kanevskiy : oops, more aggressive caching - of names opened old bugs: ip started to print garbage in some places. - * Robert Olsson, rt_cache_stat. Renamed to rtstat. - * An old bug in "ip maddr ls": reduntant empty lines in output. - Seeing this crap for ages but lucky match of desire/ability to repair - and a huff about this happened only today. :-) - * "Mr. James W. Laferriere" - doc: option to produce ps output for non-a4 and not only 2 pages/sheet. - * Jamal's patch for ingres qdisc. - * Bernd Eckenfels : deleted orphaned bogus #include - in include/utils.h. - * Julian Anastasov : uninitialized fields in nexthop - producing funny "dead" nexthops in multipath routes. - Stupid me, look at the first line in [010803]... Was it difficult to guess - this that time? People blame for several months. :-) - Special thanks to bert hubert who raised the issue in netdev. - Thanks and apologies to Terry Schmidt , - Ruben Puettmann , - Mark Ivens . - * willy tarreau : "make install" target. - * Tunable limit for sch_sfq. Patch to kernel activating this - is about to be submitted. Reminded by Adi Nugroho . - -[010824] - * ip address add sets scope of loopback addreses to "host". - Advised by David Miller. - * ZIP! and David Ford - Some strcpy's changed to strncpy's. - * David Ford , test for compilation with gcc3. - * David Ford . Damn, I broke rtnl_talk in previous - snapshot. - -[010803] - * If "dev" is not specified in multipath route, ifindex remained - uninitialized. Grr. Thanks to Kunihiro Ishiguro . - * Rafal Maszkowski , batch mode tc. The most old patch. - * Updates list of data protocol ids. - Lots of reporters. I bring my apologies. - * Jan Rekorajski . Updated list of datalink types. - * Christina Chen . Bug in parsing IPv6 address match in u32. - * Pekka Savola . ip -6 route flush dev lo stuck - on deleting root of the table. - * Werner. dsmark fixes. - * Alexander Demenshin . Old miracleous bug - in ip monitor. It was puzzle, people permanently blame that - it prints some crap. - * Rui Prior . f_route failed to resolve fromif. - Werner also noticed this and sent patch. Bad place... [RETHINK] - * Kim Woelders . - - changes in Makefile for cross-compile - - understand "all" as alias for "any" - - bug in iprule.c -! [ NB. Also he sent patch for kernel. Do not forget! ] - * Werner. Fix to tc core files: wrong exits etc. - * Bernd Jendrissek . Some sanitizations of tc.c -!* Marian Jancar . He say q_tbf prints wrong latency! -! Seems, he is wrong. - * Werner (and Nikolai Vladychevski ) check ->print_copts - to avoid segfault. - -[001007] - * Compiles under rh-7.0 - -[000928] - * Sorry. I have lost all the CVS with changes made since 000305. - If someone sent me a patch after this date, please, resubmit. - Restored from the last backup and mailboxes: - - * Edit ip-cref.tex by raf . - * RTAX_REORDERING support. - * IFLA_MASTER support. - * Bug in rtnl_talk(), libnetlink.c. Reported by David P. Olshfski - - -[000305] - * Bugs in RESOLVE_HOSTNAMES. Bratislav Ilich - * ARPHRD_IEEE802_TR - -[000225] - * ECN in q_red.c. - -[000221] - * diffserv update from Jamal Hadi Salim - * Some bits of IPX from Steve Whitehouse. - * ATM qdisc from Werner Almesberger - * Support for new attributes on routes in linux-2.3. - -[991023] - No news, only several bugs are fixed. - * Since ss990630 "ip rule list" printed wrong prefix length. - Vladimir V. Ivanov - * "ip rule" parsed >INT_MAX values of metric incorrectly. - Matthew G. Marsh - * Some improvements in doc/Makefile advised by - Andi Kleen and Werner Almesberger. - -[990824] - * new attributes in "ip route": rtt, rttvar, cwnd, ssthresh and advmss. - * some updates in documentaion to reflect new status. - -[990630] - * DiffServ support. - Werner Almesberger - Jamal Hadi Salim - * DECnet support. - Steve Whitehouse - * Some minor tweaks in docs and code. - -[990530] - * routel script. Stephen R. van den Berg - * Bug in tc/q_prio.c resetting priomap. Reported by - Ole Husgaard and - Jan Kasprzak - * IP command reference manual is published (ip-cref.tex). - I am sorry, but tc-cref.tex is still not ready, to be more - exact the draft does not describe current tc 8-) - * ip, rtmon, rtacct utilities are updated according to manual 8-) - Lots of changes: - - (MAIN) "flush" command for addr, neigh and route. - - error messages are sanitized; now it does not print - usage() page on each error. - - output format is improved. - - "oneline" mode is added. - - etc. - * Name databases; resolution acsii <-> numeric is split out to lib/* - * scripts ifcfg, ifone and rtpr. - * examples/dhcp-client-script is copied from my patch to ISC dhcp. - * Makefile in doc/ directory. - -[990417] - * "pmtudisc" flag to "ip tunnel". Phil Karn - * bug in tc/q_tbf.c preventing setting peak_rate, Martin Mares - * doc/flowlabels.tex - -[990329] - - * This snapshot fixes some compatibility problems, which I introduced - occasionally to previous snapshots. - * Namely, "allot" to "tc qdisc add ... cbq" is accepted but ignored. - * Another changes are supposed to be shown in the next snapshot, but - because of troubles with "allot" I am forced to release premature - version. Namely, "cell", "prio", "weight" etc. are optional now. - * doc/ip-tunnels.tex - -[990327] - * History was not recorded. - -[981002] - * Rani Assaf contributed resolving - addresses to names. - BEWARE! DO NOT USE THIS OPTION, WHEN REPORTING BUGS IN - IPROUTE OR IN KERENEL. ALL THE BUG REPORTS MUST CONTAIN - ONLY NUMERIC ADDRESSES. - -[981101] - * now it should compile for any libc. diff --git a/configure b/configure deleted file mode 100755 index dc14e54..0000000 --- a/configure +++ /dev/null @@ -1,27 +0,0 @@ -#! /bin/bash -# This is not an autconf generated configure -# -INCLUDE=${1:-"$PWD/include"} - -echo "# Generated config based on" $INCLUDE >Config - -echo "TC schedulers" - -echo -n " ATM " -cat >/tmp/atmtest.c < -int main(int argc, char **argv) { - struct atm_qos qos; - (void) text2qos("aal5,ubr:sdu=9180,rx:none",&qos,0); - return 0; -} -EOF -gcc -I$INCLUDE -o /tmp/atmtest /tmp/atmtest.c -latm >/dev/null 2>&1 -if [ $? -eq 0 ] -then - echo "TC_CONFIG_ATM:=y" >>Config - echo yes -else - echo no -fi -rm -f /tmp/atmtest.c /tmp/atmtest diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 84836a2..0000000 --- a/doc/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -PSFILES=ip-cref.ps ip-tunnels.ps api-ip6-flowlabels.ps ss.ps nstat.ps arpd.ps rtstat.ps -# tc-cref.ps -# api-rtnl.tex api-pmtudisc.tex api-news.tex -# iki-netdev.ps iki-neighdst.ps - - -LATEX=latex -DVIPS=dvips -SGML2DVI=sgml2latex --output=dvi -SGML2HTML=sgml2html -s 0 -LPR=lpr -Zsduplex -SHELL=bash -PAGESIZE=a4 -PAGESPERPAGE=2 - -HTMLFILES=$(subst .sgml,.html,$(shell echo *.sgml)) -DVIFILES=$(subst .ps,.dvi,$(PSFILES)) - - -all: pstwocol - -pstwocol: $(PSFILES) - -html: $(HTMLFILES) - -dvi: $(DVIFILES) - -print: $(PSFILES) - $(LPR) $(PSFILES) - -%.dvi: %.sgml - $(SGML2DVI) $< - -%.dvi: %.tex - @set -e; pass=2; echo "Running LaTeX $<"; \ - while [ `$(LATEX) $< &1 | \ - grep -c '^\(LaTeX Warning: Label(s) may\|No file \|! Emergency stop\)'` -ge 1 ]; do \ - if [ $$pass -gt 3 ]; then \ - echo "Seems, something is wrong. Try by hands." ; exit 1 ; \ - fi; \ - echo "Re-running LaTeX $<, $${pass}d pass"; pass=$$[$$pass + 1]; \ - done - -%.ps: %.dvi - $(DVIPS) $< -o $@ - -%.html: %.sgml - $(SGML2HTML) $< - -install: - install -m 0644 $(shell echo *.tex) $(DESTDIR)$(DOCDIR) - install -m 0644 $(shell echo *.sgml) $(DESTDIR)$(DOCDIR) - -clean: - rm -f *.aux *.log *.toc $(PSFILES) $(DVIFILES) *.html diff --git a/doc/Plan b/doc/Plan deleted file mode 100644 index 55f478e..0000000 --- a/doc/Plan +++ /dev/null @@ -1,16 +0,0 @@ -Partially finished work. - -1. User Reference manuals. -1.1 IP Command reference (ip-cref.tex, published) -1.2 TC Command reference (tc-cref.tex) -1.3 IP tunnels (ip-tunnels.tex, published) - -2. Linux-2.2 Networking API -2.1 RTNETLINK (api-rtnl.tex) -2.2 Path MTU Discovery (api-pmtudisc.tex) -2.3 IPv6 Flow Labels (api-ip6-flowlabels.tex, published) -2.4 Miscellaneous extensions (api-misc.tex) - -3. Linux-2.2 Networking Intra-Kernel Interfaces -3.1 NetDev --- Networking Devices and netdev... (iki-netdev.tex) -3.2 Neighbour cache and destination cache. (iki-neighdst.tex) diff --git a/doc/SNAPSHOT.tex b/doc/SNAPSHOT.tex deleted file mode 100644 index 7ed0298..0000000 --- a/doc/SNAPSHOT.tex +++ /dev/null @@ -1 +0,0 @@ -\def\Draft{020116} diff --git a/doc/actions/actions-general b/doc/actions/actions-general deleted file mode 100644 index bb2295d..0000000 --- a/doc/actions/actions-general +++ /dev/null @@ -1,254 +0,0 @@ - -This documented is slightly dated but should give you idea of how things -work. - -What is it? ------------ - -An extension to the filtering/classification architecture of Linux Traffic -Control. -Up to 2.6.8 the only action that could be "attached" to a filter was policing. -i.e you could say something like: - ------ -tc filter add dev lo parent ffff: protocol ip prio 10 u32 match ip src \ -127.0.0.1/32 flowid 1:1 police mtu 4000 rate 1500kbit burst 90k ------ - -which implies "if a packet is seen on the ingress of the lo device with -a source IP address of 127.0.0.1/32 we give it a classification id of 1:1 and -we execute a policing action which rate limits its bandwidth utilization -to 1.5Mbps". - -The new extensions allow for more than just policing actions to be added. -They are also fully backward compatible. If you have a kernel that doesnt -understand them, then the effect is null i.e if you have a newer tc -but older kernel, the actions are not installed. Likewise if you -have a newer kernel but older tc, obviously the tc will use current -syntax which will work fine. Of course to get the required effect you need -both newer tc and kernel. If you are reading this you have the -right tc ;-> - -A side effect is that we can now get stateless firewalling to work with tc. -Essentially this is now an alternative to iptables. -I wont go into details of my dislike for iptables at times, but -scalability is one of the main issues; however, if you need stateful -classification - use netfilter (for now). - -This stuff works on both ingress and egress qdiscs. - -Features --------- - -1) new additional syntax and actions enabled. Note old syntax is still valid. - -Essentially this is still the same syntax as tc with a new construct -"action". The syntax is of the form: -tc filter add parent 1:0 protocol ip prio 10 -flowid 1:1 action * - -You can have as many actions as you want (within sensible reasoning). - -In the past the only real action was the policer; i.e you could do something -along the lines of: -tc filter add dev lo parent ffff: protocol ip prio 10 u32 \ -match ip src 127.0.0.1/32 flowid 1:1 \ -police mtu 4000 rate 1500kbit burst 90k - -Although you can still use the same syntax, now you can say: - -tc filter add dev lo parent 1:0 protocol ip prio 10 u32 \ -match ip src 127.0.0.1/32 flowid 1:1 \ -action police mtu 4000 rate 1500kbit burst 90k - -" generic Actions" (gact) at the moment are: -{ drop, pass, reclassify, continue} -(If you have others, no listed here give me a reason and we will add them) -+drop says to drop the packet -+pass says to accept it -+reclassify requests for reclassification of the packet -+continue requests for next lookup to match - -2)In order to take advantage of some of the targets written by the -iptables people, a classifier can have a packet being massaged by an -iptable target. I have only tested with mangler targets up to now. -(infact anything that is not in the mangling table is disabled right now) - -In terms of hooks: -*ingress is mapped to pre-routing hook -*egress is mapped to post-routing hook -I dont see much value in the other hooks, if you see it and email me good -reasons, the addition is trivial. - -Example syntax for iptables targets usage becomes: -tc filter add ..... u32 action ipt -j - -example: -tc filter add dev lo parent ffff: protocol ip prio 8 u32 \ -match ip dst 127.0.0.8/32 flowid 1:12 \ -action ipt -j mark --set-mark 2 - -3) A feature i call pipe -The motivation is derived from Unix pipe mechanism but applied to packets. -Essentially take a matching packet and pass it through -action1 | action2 | action3 etc. -You could do something similar to this with the tc policer and the "continue" -operator but this rather restricts it to just the policer and requires -multiple rules (and lookups, hence quiet inefficient); - -as an example -- and please note that this is just an example _not_ The -Word Youve Been Waiting For (yes i have had problems giving examples -which ended becoming dogma in documents and people modifying them a little -to look clever); - -i selected the metering rates to be small so that i can show better how -things work. - -The script below does the following: -- an incoming packet from 10.0.0.21 is first given a firewall mark of 1. - -- It is then metered to make sure it does not exceed its allocated rate of -1Kbps. If it doesnt exceed rate, this is where we terminate action execution. - -- If it does exceed its rate, its "color" changes to a mark of 2 and it is -then passed through a second meter. - --The second meter is shared across all flows on that device [i am suprised -that this seems to be not a well know feature of the policer; Bert was telling -me that someone was writing a qdisc just to do sharing across multiple devices; -it must be the summer heat again; weve had someone doing that every year around -summer -- the key to sharing is to use a operator "index" in your policer -rules (example "index 20"). All your rules have to use the same index to -share.] - --If the second meter is exceeded the color of the flow changes further to 3. - --We then pass the packet to another meter which is shared across all devices -in the system. If this meter is exceeded we drop the packet. - -Note the mark can be used further up the system to do things like policy -or more interesting things on the egress. - ------------------- cut here ------------------------------- -# -# Add an ingress qdisc on eth0 -tc qdisc add dev eth0 ingress -# -#if you see an incoming packet from 10.0.0.21 -tc filter add dev eth0 parent ffff: protocol ip prio 1 \ -u32 match ip src 10.0.0.21/32 flowid 1:15 \ -# -# first give it a mark of 1 -action ipt -j mark --set-mark 1 index 2 \ -# -# then pass it through a policer which allows 1kbps; if the flow -# doesnt exceed that rate, this is where we stop, if it exceeds we -# pipe the packet to the next action -action police rate 1kbit burst 9k pipe \ -# -# which marks the packet fwmark as 2 and pipes -action ipt -j mark --set-mark 2 \ -# -# next attempt to borrow b/width from a meter -# used across all flows incoming on eth0("index 30") -# and if that is exceeded we pipe to the next action -action police index 30 mtu 5000 rate 1kbit burst 10k pipe \ -# mark it as fwmark 3 if exceeded -action ipt -j mark --set-mark 3 \ -# and then attempt to borrow from a meter used by all devices in the -# system. Should this be exceeded, drop the packet on the floor. -action police index 20 mtu 5000 rate 1kbit burst 90k drop ---------------------------------- - -Now lets see the actions installed with -"tc filter show parent ffff: dev eth0" - --------- output ----------- -jroot# tc filter show parent ffff: dev eth0 -filter protocol ip pref 1 u32 -filter protocol ip pref 1 u32 fh 800: ht divisor 1 -filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:15 - - action order 1: tablename: mangle hook: NF_IP_PRE_ROUTING - target MARK set 0x1 index 2 - - action order 2: police 1 action pipe rate 1Kbit burst 9Kb mtu 2Kb - - action order 3: tablename: mangle hook: NF_IP_PRE_ROUTING - target MARK set 0x2 index 1 - - action order 4: police 30 action pipe rate 1Kbit burst 10Kb mtu 5000b - - action order 5: tablename: mangle hook: NF_IP_PRE_ROUTING - target MARK set 0x3 index 3 - - action order 6: police 20 action drop rate 1Kbit burst 90Kb mtu 5000b - - match 0a000015/ffffffff at 12 -------------------------------- - -Note the ordering of the actions is based on the order in which we entered -them. In the future i will add explicit priorities. - -Now lets run a ping -f from 10.0.0.21 to this host; stop the ping after -you see a few lines of dots - ----- -[root@jzny hadi]# ping -f 10.0.0.22 -PING 10.0.0.22 (10.0.0.22): 56 data bytes -.................................................................................................................................................................................................................................................................................................................................................................................................................................................... ---- 10.0.0.22 ping statistics --- -2248 packets transmitted, 1811 packets received, 19% packet loss -round-trip min/avg/max = 0.7/9.3/20.1 ms ------------------------------ - -Now lets take a look at the stats with "tc -s filter show parent ffff: dev eth0" - --------------- -jroot# tc -s filter show parent ffff: dev eth0 -filter protocol ip pref 1 u32 -filter protocol ip pref 1 u32 fh 800: ht divisor 1 -filter protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 -5 - - action order 1: tablename: mangle hook: NF_IP_PRE_ROUTING - target MARK set 0x1 index 2 - Sent 188832 bytes 2248 pkts (dropped 0, overlimits 0) - - action order 2: police 1 action pipe rate 1Kbit burst 9Kb mtu 2Kb - Sent 188832 bytes 2248 pkts (dropped 0, overlimits 2122) - - action order 3: tablename: mangle hook: NF_IP_PRE_ROUTING - target MARK set 0x2 index 1 - Sent 178248 bytes 2122 pkts (dropped 0, overlimits 0) - - action order 4: police 30 action pipe rate 1Kbit burst 10Kb mtu 5000b - Sent 178248 bytes 2122 pkts (dropped 0, overlimits 1945) - - action order 5: tablename: mangle hook: NF_IP_PRE_ROUTING - target MARK set 0x3 index 3 - Sent 163380 bytes 1945 pkts (dropped 0, overlimits 0) - - action order 6: police 20 action drop rate 1Kbit burst 90Kb mtu 5000b - Sent 163380 bytes 1945 pkts (dropped 0, overlimits 437) - - match 0a000015/ffffffff at 12 -------------------------------- - -Neat, eh? - - -Wanna write an action module? ------------------------------- -Its easy. Either look at the code or send me email. I will document at -some point; will also accept documentation. - -TODO ----- - -Lotsa goodies/features coming. Requests also being accepted. -At the moment the focus has been on getting the architecture in place. -Expect new things in the spurious time i have to work on this -(particularly around end of year when i have typically get time off -from work). - diff --git a/doc/actions/dummy-README b/doc/actions/dummy-README deleted file mode 100644 index 3ef9f21..0000000 --- a/doc/actions/dummy-README +++ /dev/null @@ -1,155 +0,0 @@ - -Advantage over current IMQ; cleaner in particular in in SMP; -with a _lot_ less code. -Old Dummy device functionality is preserved while new one only -kicks in if you use actions. - -IMQ USES --------- -As far as i know the reasons listed below is why people use IMQ. -It would be nice to know of anything else that i missed. - -1) qdiscs/policies that are per device as opposed to system wide. -IMQ allows for sharing. - -2) Allows for queueing incoming traffic for shaping instead of -dropping. I am not aware of any study that shows policing is -worse than shaping in achieving the end goal of rate control. -I would be interested if anyone is experimenting. - -3) Very interesting use: if you are serving p2p you may wanna give -preference to your own localy originated traffic (when responses come back) -vs someone using your system to do bittorent. So QoSing based on state -comes in as the solution. What people did to achive this was stick -the IMQ somewhere prelocal hook. -I think this is a pretty neat feature to have in Linux in general. -(i.e not just for IMQ). -But i wont go back to putting netfilter hooks in the device to satisfy -this. I also dont think its worth it hacking dummy some more to be -aware of say L3 info and play ip rule tricks to achieve this. ---> Instead the plan is to have a contrack related action. This action will -selectively either query/create contrack state on incoming packets. -Packets could then be redirected to dummy based on what happens -> eg -on incoming packets; if we find they are of known state we could send to -a different queue than one which didnt have existing state. This -all however is dependent on whatever rules the admin enters. - -At the moment this function does not exist yet. I have decided instead -of sitting on the patch to release it and then if theres pressure i will -add this feature. - -What you can do with dummy currently with actions --------------------------------------------------- - -Lets say you are policing packets from alias 192.168.200.200/32 -you dont want those to exceed 100kbps going out. - -tc filter add dev eth0 parent 1: protocol ip prio 10 u32 \ -match ip src 192.168.200.200/32 flowid 1:2 \ -action police rate 100kbit burst 90k drop - -If you run tcpdump on eth0 you will see all packets going out -with src 192.168.200.200/32 dropped or not -Extend the rule a little to see only the ones that made it out: - -tc filter add dev eth0 parent 1: protocol ip prio 10 u32 \ -match ip src 192.168.200.200/32 flowid 1:2 \ -action police rate 10kbit burst 90k drop \ -action mirred egress mirror dev dummy0 - -Now fire tcpdump on dummy0 to see only those packets .. -tcpdump -n -i dummy0 -x -e -t - -Essentially a good debugging/logging interface. - -If you replace mirror with redirect, those packets will be -blackholed and will never make it out. This redirect behavior -changes with new patch (but not the mirror). - -What you can do with the patch to provide functionality -that most people use IMQ for below: - --------- -export TC="/sbin/tc" - -$TC qdisc add dev dummy0 root handle 1: prio -$TC qdisc add dev dummy0 parent 1:1 handle 10: sfq -$TC qdisc add dev dummy0 parent 1:2 handle 20: tbf rate 20kbit buffer 1600 limit 3000 -$TC qdisc add dev dummy0 parent 1:3 handle 30: sfq -$TC filter add dev dummy0 protocol ip pref 1 parent 1: handle 1 fw classid 1:1 -$TC filter add dev dummy0 protocol ip pref 2 parent 1: handle 2 fw classid 1:2 - -ifconfig dummy0 up - -$TC qdisc add dev eth0 ingress - -# redirect all IP packets arriving in eth0 to dummy0 -# use mark 1 --> puts them onto class 1:1 -$TC filter add dev eth0 parent ffff: protocol ip prio 10 u32 \ -match u32 0 0 flowid 1:1 \ -action ipt -j MARK --set-mark 1 \ -action mirred egress redirect dev dummy0 - --------- - - -Run A Little test: - -from another machine ping so that you have packets going into the box: ------ -[root@jzny action-tests]# ping 10.22 -PING 10.22 (10.0.0.22): 56 data bytes -64 bytes from 10.0.0.22: icmp_seq=0 ttl=64 time=2.8 ms -64 bytes from 10.0.0.22: icmp_seq=1 ttl=64 time=0.6 ms -64 bytes from 10.0.0.22: icmp_seq=2 ttl=64 time=0.6 ms - ---- 10.22 ping statistics --- -3 packets transmitted, 3 packets received, 0% packet loss -round-trip min/avg/max = 0.6/1.3/2.8 ms -[root@jzny action-tests]# ------ -Now look at some stats: - ---- -[root@jmandrake]:~# $TC -s filter show parent ffff: dev eth0 -filter protocol ip pref 10 u32 -filter protocol ip pref 10 u32 fh 800: ht divisor 1 -filter protocol ip pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 - match 00000000/00000000 at 0 - action order 1: tablename: mangle hook: NF_IP_PRE_ROUTING - target MARK set 0x1 - index 1 ref 1 bind 1 installed 4195sec used 27sec - Sent 252 bytes 3 pkts (dropped 0, overlimits 0) - - action order 2: mirred (Egress Redirect to device dummy0) stolen - index 1 ref 1 bind 1 installed 165 sec used 27 sec - Sent 252 bytes 3 pkts (dropped 0, overlimits 0) - -[root@jmandrake]:~# $TC -s qdisc -qdisc sfq 30: dev dummy0 limit 128p quantum 1514b - Sent 0 bytes 0 pkts (dropped 0, overlimits 0) -qdisc tbf 20: dev dummy0 rate 20Kbit burst 1575b lat 2147.5s - Sent 210 bytes 3 pkts (dropped 0, overlimits 0) -qdisc sfq 10: dev dummy0 limit 128p quantum 1514b - Sent 294 bytes 3 pkts (dropped 0, overlimits 0) -qdisc prio 1: dev dummy0 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 - Sent 504 bytes 6 pkts (dropped 0, overlimits 0) -qdisc ingress ffff: dev eth0 ---------------- - Sent 308 bytes 5 pkts (dropped 0, overlimits 0) - -[root@jmandrake]:~# ifconfig dummy0 -dummy0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 - inet6 addr: fe80::200:ff:fe00:0/64 Scope:Link - UP BROADCAST RUNNING NOARP MTU:1500 Metric:1 - RX packets:6 errors:0 dropped:3 overruns:0 frame:0 - TX packets:3 errors:0 dropped:0 overruns:0 carrier:0 - collisions:0 txqueuelen:32 - RX bytes:504 (504.0 b) TX bytes:252 (252.0 b) ------ - -Dummy continues to behave like it always did. -You send it any packet not originating from the actions it will drop them. -[In this case the three dropped packets were ipv6 ndisc]. - -cheers, -jamal diff --git a/doc/actions/gact-usage b/doc/actions/gact-usage deleted file mode 100644 index de1308d..0000000 --- a/doc/actions/gact-usage +++ /dev/null @@ -1,79 +0,0 @@ - -gact [RAND] [INDEX] - -Where: - ACTION := reclassify | drop | continue | pass | ok - RAND := random - RANDTYPE := netrand | determ - VAL : = value not exceeding 10000 - INDEX := index value used - -ACTION semantics -- pass and ok are equivalent to accept -- continue allows to restart classification lookup -- drop drops packets -- reclassify implies continue classification where we left off - -randomization --------------- - -At the moment there are only two algorithms. One is deterministic -and the other uses internal kernel netrand. - -Examples: - -Rules can be installed on both ingress and egress - this shows ingress -only - -tc qdisc add dev eth0 ingress - -# example 1 -tc filter add dev eth0 parent ffff: protocol ip prio 6 u32 match ip src \ -10.0.0.9/32 flowid 1:16 action drop - -ping -c 20 10.0.0.9 - --- -filter u32 -filter u32 fh 800: ht divisor 1 -filter u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:16 (rule hit 32 success 20) - match 0a000009/ffffffff at 12 (success 20 ) - action order 1: gact action drop - random type none pass val 0 - index 1 ref 1 bind 1 installed 59 sec used 35 sec - Sent 1680 bytes 20 pkts (dropped 20, overlimits 0 ) - ----- - -# example 2 -#allow 1 out 10 randomly using the netrand generator -tc filter add dev eth0 parent ffff: protocol ip prio 6 u32 match ip src \ -10.0.0.9/32 flowid 1:16 action drop random netrand ok 10 - -ping -c 20 10.0.0.9 - ----- -filter protocol ip pref 6 u32 filter protocol ip pref 6 u32 fh 800: ht divisor 1filter protocol ip pref 6 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:16 (rule hit 20 success 20) - match 0a000009/ffffffff at 12 (success 20 ) - action order 1: gact action drop - random type netrand pass val 10 - index 5 ref 1 bind 1 installed 49 sec used 25 sec - Sent 1680 bytes 20 pkts (dropped 16, overlimits 0 ) - --------- -#alternative: deterministically accept every second packet -tc filter add dev eth0 parent ffff: protocol ip prio 6 u32 match ip src \ -10.0.0.9/32 flowid 1:16 action drop random determ ok 2 - -ping -c 20 10.0.0.9 - -tc -s filter show parent ffff: dev eth0 ------ -filter protocol ip pref 6 u32 filter protocol ip pref 6 u32 fh 800: ht divisor 1filter protocol ip pref 6 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:16 (rule hit 20 success 20) - match 0a000009/ffffffff at 12 (success 20 ) - action order 1: gact action drop - random type determ pass val 2 - index 4 ref 1 bind 1 installed 118 sec used 82 sec - Sent 1680 bytes 20 pkts (dropped 10, overlimits 0 ) ------ - diff --git a/doc/actions/mirred-usage b/doc/actions/mirred-usage deleted file mode 100644 index aa942e5..0000000 --- a/doc/actions/mirred-usage +++ /dev/null @@ -1,71 +0,0 @@ - -Very funky action. I do plan to add to a few more things to it -This is the basic stuff. Idea borrowed from the way ethernet switches -mirror and redirect packets. - -Usage: - -mirred [index INDEX] -where: -DIRECTION := -ACTION := -INDEX is the specific policy instance id -DEVICENAME is the devicename - - -Mirroring essentially takes a copy of the packet whereas redirecting -steals the packet and redirects to specified destination. - -Some examples: -Host A is hooked up to us on eth0 - -tc qdisc add dev lo ingress -# redirect all packets arriving on ingress of lo to eth0 -tc filter add dev lo parent ffff: protocol ip prio 10 u32 \ -match u32 0 0 flowid 1:2 action mirred egress redirect dev eth0 - -On host A start a tcpdump on interface connecting to us. - -on our host ping -c 2 127.0.0.1 - -Ping would fail sinc all packets are heading out eth0 -tcpudmp on host A would show them - -if you substitute the redirect with mirror above as in: -tc filter add dev lo parent ffff: protocol ip prio 10 u32 \ -match u32 0 0 flowid 1:2 action mirred egress mirror dev eth0 - -Then you should see the packets on both host A and the local -stack (i.e ping would work). - -Even more funky example: - -# -#allow 1 out 10 packets to randomly make it to the -# host A (Randomness uses the netrand generator) -# -tc filter add dev lo parent ffff: protocol ip prio 10 u32 \ -match u32 0 0 flowid 1:2 \ -action drop random determ ok 10\ -action mirred egress mirror dev eth0 - ------- -Example 2: -# for packets coming from 10.0.0.9: -#Redirect packets on egress (to ISP A) if you exceed a certain rate -# to eth1 (to ISP B) if you exceed a certain rate -# - -tc qdisc add dev eth0 handle 1:0 root prio - -tc filter add dev eth0 parent 1:0 protocol ip prio 6 u32 \ -match ip src 10.0.0.9/32 flowid 1:16 \ -action police rate 100kbit burst 90k ok \ -action mirred egress mirror dev eth1 - ---- - -A more interesting example is when you mirror flows to a dummy device -so you could tcpdump them (dummy by defaults drops all packets it sees). -This is a very useful debug feature. - diff --git a/doc/api-ip6-flowlabels.tex b/doc/api-ip6-flowlabels.tex deleted file mode 100644 index aa34e94..0000000 --- a/doc/api-ip6-flowlabels.tex +++ /dev/null @@ -1,429 +0,0 @@ -\documentstyle[12pt,twoside]{article} -\def\TITLE{IPv6 Flow Labels} -\input preamble -\begin{center} -\Large\bf IPv6 Flow Labels in Linux-2.2. -\end{center} - - -\begin{center} -{ \large Alexey~N.~Kuznetsov } \\ -\em Institute for Nuclear Research, Moscow \\ -\verb|kuznet@ms2.inr.ac.ru| \\ -\rm April 11, 1999 -\end{center} - -\vspace{5mm} - -\tableofcontents - -\section{Introduction.} - -Every IPv6 packet carries 28 bits of flow information. RFC2460 splits -these bits to two fields: 8 bits of traffic class (or DS field, if you -prefer this term) and 20 bits of flow label. Currently there exist -no well-defined API to manage IPv6 flow information. In this document -I describe an attempt to design the API for Linux-2.2 IPv6 stack. - -\vskip 1mm - -The API must solve the following tasks: - -\begin{enumerate} - -\item To allow user to set traffic class bits. - -\item To allow user to read traffic class bits of received packets. -This feature is not so useful as the first one, however it will be -necessary f.e.\ to implement ECN [RFC2481] for datagram oriented services -or to implement receiver side of SRP or another end-to-end protocol -using traffic class bits. - -\item To assign flow labels to packets sent by user. - -\item To get flow labels of received packets. I do not know -any applications of this feature, but it is possible that receiver will -want to use flow labels to distinguish sub-flows. - -\item To allocate flow labels in the way, compliant to RFC2460. Namely: - -\begin{itemize} -\item -Flow labels must be uniformly distributed (pseudo-)random numbers, -so that any subset of 20 bits can be used as hash key. - -\item -Flows with coinciding source address and flow label must have identical -destination address and not-fragmentable extensions headers (i.e.\ -hop by hop options and all the headers up to and including routing header, -if it is present.) - -\begin{NB} -There is a hole in specs: some hop-by-hop options can be -defined only on per-packet base (f.e.\ jumbo payload option). -Essentially, it means that such options cannot present in packets -with flow labels. -\end{NB} -\begin{NB} -NB notes here and below reflect only my personal opinion, -they should be read with smile or should not be read at all :-). -\end{NB} - - -\item -Flow labels have finite lifetime and source is not allowed to reuse -flow label for another flow within the maximal lifetime has expired, -so that intermediate nodes will be able to invalidate flow state before -the label is taken over by another flow. -Flow state, including lifetime, is propagated along datagram path -by some application specific methods -(f.e.\ in RSVP PATH messages or in some hop-by-hop option). - - -\end{itemize} - -\end{enumerate} - -\section{Sending/receiving flow information.} - -\paragraph{Discussion.} -\addcontentsline{toc}{subsection}{Discussion} -It was proposed (Where? I do not remember any explicit statement) -to solve the first four tasks using -\verb|sin6_flowinfo| field added to \verb|struct| \verb|sockaddr_in6| -(see RFC2553). - -\begin{NB} - This method is difficult to consider as reasonable, because it - puts additional overhead to all the services, despite of only - very small subset of them (none, to be more exact) really use it. - It contradicts both to IETF spirit and the letter. Before RFC2553 - one justification existed, IPv6 address alignment left 4 byte - hole in \verb|sockaddr_in6| in any case. Now it has no justification. -\end{NB} - -We have two problems with this method. The first one is common for all OSes: -if \verb|recvmsg()| initializes \verb|sin6_flowinfo| to flow info -of received packet, we loose one very important property of BSD socket API, -namely, we are not allowed to use received address for reply directly -and have to mangle it, even if we are not interested in flowinfo subtleties. - -\begin{NB} - RFC2553 adds new requirement: to clear \verb|sin6_flowinfo|. - Certainly, it is not solution but rather attempt to force applications - to make unnecessary work. Well, as usually, one mistake in design - is followed by attempts to patch the hole and more mistakes... -\end{NB} - -Another problem is Linux specific. Historically Linux IPv6 did not -initialize \verb|sin6_flowinfo| at all, so that, if kernel does not -support flow labels, this field is not zero, but a random number. -Some applications also did not take care about it. - -\begin{NB} -Following RFC2553 such applications can be considered as broken, -but I still think that they are right: clearing all the address -before filling known fields is robust but stupid solution. -Useless wasting CPU cycles and -memory bandwidth is not a good idea. Such patches are acceptable -as temporary hacks, but not as standard of the future. -\end{NB} - - -\paragraph{Implementation.} -\addcontentsline{toc}{subsection}{Implementation} -By default Linux IPv6 does not read \verb|sin6_flowinfo| field -assuming that common applications are not obliged to initialize it -and are permitted to consider it as pure alignment padding. -In order to tell kernel that application -is aware of this field, it is necessary to set socket option -\verb|IPV6_FLOWINFO_SEND|. - -\begin{verbatim} - int on = 1; - setsockopt(sock, SOL_IPV6, IPV6_FLOWINFO_SEND, - (void*)&on, sizeof(on)); -\end{verbatim} - -Linux kernel never fills \verb|sin6_flowinfo| field, when passing -message to user space, though the kernels which support flow labels -initialize it to zero. If user wants to get received flowinfo, he -will set option \verb|IPV6_FLOWINFO| and after this he will receive -flowinfo as ancillary data object of type \verb|IPV6_FLOWINFO| -(cf.\ RFC2292). - -\begin{verbatim} - int on = 1; - setsockopt(sock, SOL_IPV6, IPV6_FLOWINFO, (void*)&on, sizeof(on)); -\end{verbatim} - -Flowinfo received and latched by a connected TCP socket also may be fetched -with \verb|getsockopt()| \verb|IPV6_PKTOPTIONS| together with -another optional information. - -Besides that, in the spirit of RFC2292 the option \verb|IPV6_FLOWINFO| -may be used as alternative way to send flowinfo with \verb|sendmsg()| or -to latch it with \verb|IPV6_PKTOPTIONS|. - -\paragraph{Note about IPv6 options and destination address.} -\addcontentsline{toc}{subsection}{IPv6 options and destination address} -If \verb|sin6_flowinfo| does contain not zero flow label, -destination address in \verb|sin6_addr| and non-fragmentable -extension headers are ignored. Instead, kernel uses the values -cached at flow setup (see below). However, for connected sockets -kernel prefers the values set at connection time. - -\paragraph{Example.} -\addcontentsline{toc}{subsection}{Example} -After setting socket option \verb|IPV6_FLOWINFO| -flowlabel and DS field are received as ancillary data object -of type \verb|IPV6_FLOWINFO| and level \verb|SOL_IPV6|. -In the cases when it is convenient to use \verb|recvfrom(2)|, -it is possible to replace library variant with your own one, -sort of: - -\begin{verbatim} -#include -#include - -size_t recvfrom(int fd, char *buf, size_t len, int flags, - struct sockaddr *addr, int *addrlen) -{ - size_t cc; - char cbuf[128]; - struct cmsghdr *c; - struct iovec iov = { buf, len }; - struct msghdr msg = { addr, *addrlen, - &iov, 1, - cbuf, sizeof(cbuf), - 0 }; - - cc = recvmsg(fd, &msg, flags); - if (cc < 0) - return cc; - ((struct sockaddr_in6*)addr)->sin6_flowinfo = 0; - *addrlen = msg.msg_namelen; - for (c=CMSG_FIRSTHDR(&msg); c; c = CMSG_NEXTHDR(&msg, c)) { - if (c->cmsg_level != SOL_IPV6 || - c->cmsg_type != IPV6_FLOWINFO) - continue; - ((struct sockaddr_in6*)addr)->sin6_flowinfo = *(__u32*)CMSG_DATA(c); - } - return cc; -} -\end{verbatim} - - - -\section{Flow label management.} - -\paragraph{Discussion.} -\addcontentsline{toc}{subsection}{Discussion} -Requirements of RFC2460 are pretty tough. Particularly, lifetimes -longer than boot time require to store allocated labels at stable -storage, so that the full implementation necessarily includes user space flow -label manager. There are at least three different approaches: - -\begin{enumerate} -\item {\bf ``Cooperative''. } We could leave flow label allocation wholly -to user space. When user needs label he requests manager directly. The approach -is valid, but as any ``cooperative'' approach it suffers of security problems. - -\begin{NB} -One idea is to disallow not privileged user to allocate flow -labels, but instead to pass the socket to manager via \verb|SCM_RIGHTS| -control message, so that it will allocate label and assign it to socket -itself. Hmm... the idea is interesting. -\end{NB} - -\item {\bf ``Indirect''.} Kernel redirects requests to user level daemon -and does not install label until the daemon acknowledged the request. -The approach is the most promising, it is especially pleasant to recognize -parallel with IPsec API [RFC2367,Craig]. Actually, it may share API with -IPsec. - -\item {\bf ``Stupid''.} To allocate labels in kernel space. It is the simplest -method, but it suffers of two serious flaws: the first, -we cannot lease labels with lifetimes longer than boot time, the second, -it is sensitive to DoS attacks. Kernel have to remember all the obsolete -labels until their expiration and malicious user may fastly eat all the -flow label space. - -\end{enumerate} - -Certainly, I choose the most ``stupid'' method. It is the cheapest one -for implementor (i.e.\ me), and taking into account that flow labels -still have no serious applications it is not useful to work on more -advanced API, especially, taking into account that eventually we -will get it for no fee together with IPsec. - - -\paragraph{Implementation.} -\addcontentsline{toc}{subsection}{Implementation} -Socket option \verb|IPV6_FLOWLABEL_MGR| allows to -request flow label manager to allocate new flow label, to reuse -already allocated one or to delete old flow label. -Its argument is \verb|struct| \verb|in6_flowlabel_req|: - -\begin{verbatim} -struct in6_flowlabel_req -{ - struct in6_addr flr_dst; - __u32 flr_label; - __u8 flr_action; - __u8 flr_share; - __u16 flr_flags; - __u16 flr_expires; - __u16 flr_linger; - __u32 __flr_reserved; - /* Options in format of IPV6_PKTOPTIONS */ -}; -\end{verbatim} - -\begin{itemize} - -\item \verb|dst| is IPv6 destination address associated with the label. - -\item \verb|label| is flow label value in network byte order. If it is zero, -kernel will allocate new pseudo-random number. Otherwise, kernel will try -to lease flow label ordered by user. In this case, it is user task to provide -necessary flow label randomness. - -\item \verb|action| is requested operation. Currently, only three operations -are defined: - -\begin{verbatim} -#define IPV6_FL_A_GET 0 /* Get flow label */ -#define IPV6_FL_A_PUT 1 /* Release flow label */ -#define IPV6_FL_A_RENEW 2 /* Update expire time */ -\end{verbatim} - -\item \verb|flags| are optional modifiers. Currently -only \verb|IPV6_FL_A_GET| has modifiers: - -\begin{verbatim} -#define IPV6_FL_F_CREATE 1 /* Allowed to create new label */ -#define IPV6_FL_F_EXCL 2 /* Do not create new label */ -\end{verbatim} - - -\item \verb|share| defines who is allowed to reuse the same flow label. - -\begin{verbatim} -#define IPV6_FL_S_NONE 0 /* Not defined */ -#define IPV6_FL_S_EXCL 1 /* Label is private */ -#define IPV6_FL_S_PROCESS 2 /* May be reused by this process */ -#define IPV6_FL_S_USER 3 /* May be reused by this user */ -#define IPV6_FL_S_ANY 255 /* Anyone may reuse it */ -\end{verbatim} - -\item \verb|linger| is time in seconds. After the last user releases flow -label, it will not be reused with different destination and options at least -during this time. If \verb|share| is not \verb|IPV6_FL_S_EXCL| the label -still can be shared by another sockets. Current implementation does not allow -unprivileged user to set linger longer than 60 sec. - -\item \verb|expires| is time in seconds. Flow label will be kept at least -for this time, but it will not be destroyed before user released it explicitly -or closed all the sockets using it. Current implementation does not allow -unprivileged user to set timeout longer than 60 sec. Proviledged applications -MAY set longer lifetimes, but in this case they MUST save allocated -labels at stable storage and restore them back after reboot before the first -application allocates new flow. - -\end{itemize} - -This structure is followed by optional extension headers associated -with this flow label in format of \verb|IPV6_PKTOPTIONS|. Only -\verb|IPV6_HOPOPTS|, \verb|IPV6_RTHDR| and, if \verb|IPV6_RTHDR| presents, -\verb|IPV6_DSTOPTS| are allowed. - -\paragraph{Example.} -\addcontentsline{toc}{subsection}{Example} - The function \verb|get_flow_label| allocates -private flow label. - -\begin{verbatim} -int get_flow_label(int fd, struct sockaddr_in6 *dst, __u32 fl) -{ - int on = 1; - struct in6_flowlabel_req freq; - - memset(&freq, 0, sizeof(freq)); - freq.flr_label = htonl(fl); - freq.flr_action = IPV6_FL_A_GET; - freq.flr_flags = IPV6_FL_F_CREATE | IPV6_FL_F_EXCL; - freq.flr_share = IPV6_FL_S_EXCL; - memcpy(&freq.flr_dst, &dst->sin6_addr, 16); - if (setsockopt(fd, SOL_IPV6, IPV6_FLOWLABEL_MGR, - &freq, sizeof(freq)) == -1) { - perror ("can't lease flowlabel"); - return -1; - } - dst->sin6_flowinfo |= freq.flr_label; - - if (setsockopt(fd, SOL_IPV6, IPV6_FLOWINFO_SEND, - &on, sizeof(on)) == -1) { - perror ("can't send flowinfo"); - - freq.flr_action = IPV6_FL_A_PUT; - setsockopt(fd, SOL_IPV6, IPV6_FLOWLABEL_MGR, - &freq, sizeof(freq)); - return -1; - } - return 0; -} -\end{verbatim} - -A bit more complicated example using routing header can be found -in \verb|ping6| utility (\verb|iputils| package). Linux rsvpd backend -contains an example of using operation \verb|IPV6_FL_A_RENEW|. - -\paragraph{Listing flow labels.} -\addcontentsline{toc}{subsection}{Listing flow labels} -List of currently allocated -flow labels may be read from \verb|/proc/net/ip6_flowlabel|. - -\begin{verbatim} -Label S Owner Users Linger Expires Dst Opt -A1BE5 1 0 0 6 3 3ffe2400000000010a0020fffe71fb30 0 -\end{verbatim} - -\begin{itemize} -\item \verb|Label| is hexadecimal flow label value. -\item \verb|S| is sharing style. -\item \verb|Owner| is ID of creator, it is zero, pid or uid, depending on - sharing style. -\item \verb|Users| is number of applications using the label now. -\item \verb|Linger| is \verb|linger| of this label in seconds. -\item \verb|Expires| is time until expiration of the label in seconds. It may - be negative, if the label is in use. -\item \verb|Dst| is IPv6 destination address. -\item \verb|Opt| is length of options, associated with the label. Option - data are not accessible. -\end{itemize} - - -\paragraph{Flow labels and RSVP.} -\addcontentsline{toc}{subsection}{Flow labels and RSVP} -RSVP daemon supports IPv6 flow labels -without any modifications to standard ISI RAPI. Sender must allocate -flow label, fill corresponding sender template and submit it to local rsvp -daemon. rsvpd will check the label and start to announce it in PATH -messages. Rsvpd on sender node will renew the flow label, so that it will not -be reused before path state expires and all the intermediate -routers and receiver purge flow state. - -\verb|rtap| utility is modified to parse flow labels. F.e.\ if user allocated -flow label \verb|0xA1234|, he may write: - -\begin{verbatim} -RTAP> sender 3ffe:2400::1/FL0xA1234 -\end{verbatim} - -Receiver makes reservation with command: -\begin{verbatim} -RTAP> reserve ff 3ffe:2400::1/FL0xA1234 -\end{verbatim} - -\end{document} diff --git a/doc/arpd.sgml b/doc/arpd.sgml deleted file mode 100644 index 0ab79c6..0000000 --- a/doc/arpd.sgml +++ /dev/null @@ -1,130 +0,0 @@ - - -
- -ARPD Daemon -<author>Alexey Kuznetsov, <tt/kuznet@ms2.inr.ac.ru/ -<date>some_negative_number, 20 Sep 2001 -<abstract> -<tt/arpd/ is daemon collecting gratuitous ARP information, saving -it on local disk and feeding it to kernel on demand to avoid -redundant broadcasting due to limited size of kernel ARP cache. -</abstract> - - -<p><bf/Description/ - -<p>The format of the command is: - -<tscreen><verb> - arpd OPTIONS [ INTERFACE [ INTERFACE ... ] ] -</verb></tscreen> - -<p> <tt/OPTIONS/ are: - -<itemize> - -<item><tt/-l/ - dump <tt/arpd/ database to stdout and exit. Output consists -of three columns: interface index, IP address and MAC address. -Negative entries for dead hosts are also shown, in this case MAC address -is replaced by word <tt/FAILED/ followed by colon and time when the fact -that host is dead was proven the last time. - -<item><tt/-f FILE/ - read and load <tt/arpd/ database from <tt/FILE/ -in text format similar dumped by option <tt/-l/. Exit after load, -probably listing resulting database, if option <tt/-l/ is also given. -If <tt/FILE/ is <tt/-/, <tt/stdin/ is read to get ARP table. - -<item><tt/-b DATABASE/ - location of database file. Default location is -<tt>/var/lib/arpd/arpd.db</tt>. - -<item><tt/-a NUMBER/ - <tt/arpd/ not only passively listens ARP on wire, but -also send brodcast queries itself. <tt/NUMBER/ is number of such queries -to make before destination is considered as dead. When <tt/arpd/ is started -as kernel helper (i.e. with <tt/app_solicit/ enabled in <tt/sysctl/ -or even with option <tt/-k/) without this option and still did not learn enough -information, you can observe 1 second gaps in service. Not fatal, but -not good. - -<item><tt/-k/ - suppress sending broadcast queries by kernel. It takes -sense together with option <tt/-a/. - -<item><tt/-n TIME/ - timeout of negative cache. When resolution fails <tt/arpd/ -suppresses further attempts to resolve for this period. It makes sense -only together with option <tt/-k/. This timeout should not be too much -longer than boot time of a typical host not supporting gratuitous ARP. -Default value is 60 seconds. - -<item><tt/-R RATE/ - maximal steady rate of broadcasts sent by <tt/arpd/ -in packets per second. Default value is 1. - -<item><tt/-B NUMBER/ - number of broadcasts sent by <tt/arpd/ back to back. -Default value is 3. Together with option <tt/-R/ this option allows -to police broadcasting not to exceed <tt/B+R*T/ over any interval -of time <tt/T/. - -</itemize> - -<p><tt/INTERFACE/ is name of networking inteface to watch. -If no interfaces given, <tt/arpd/ monitors all the interfaces. -In this case <tt/arpd/ does not adjust <tt/sysctl/ parameters, -it is supposed user does this himself after <tt/arpd/ is started. - - -<p> Signals - -<p> <tt/arpd/ exits gracefully syncing database and restoring adjusted -<tt/sysctl/ parameters, when receives <tt/SIGINT/ or <tt/SIGTERM/. -<tt/SIGHUP/ syncs database to disk. <tt/SIGUSR1/ sends some statistics -to <tt/syslog/. Effect of another signals is undefined, they may corrupt -database and leave <tt/sysctl/ parameters in an unpredictable state. - -<p> Note - -<p> In order to <tt/arpd/ be able to serve as ARP resolver, kernel must be -compiled with the option <tt/CONFIG_ARPD/ and, in the case when interface list -is not given on command line, variable <tt/app_solicit/ -on interfaces of interest should be set in <tt>/proc/sys/net/ipv4/neigh/*</tt>. -If this is not made <tt/arpd/ still collects gratuitous ARP information -in its database. - -<p> Examples - -<enum> -<item> Start <tt/arpd/ to collect gratuitous ARP, but not messing -with kernel functionality: - -<tscreen><verb> - arpd -b /var/tmp/arpd.db -</verb></tscreen> - -<item> Look at result after some time: - -<tscreen><verb> - killall arpd - arpd -l -b /var/tmp/arpd.db -</verb></tscreen> - -<item> To enable kernel helper, leaving leading role to kernel: - -<tscreen><verb> - arpd -b /var/tmp/arpd.db -a 1 eth0 eth1 -</verb></tscreen> - -<item> Completely replace kernel resolution on interfaces <tt/eth0/ -and <tt/eth1/. In this case kernel still does unicast probing to -validate entries, but all the broadcast activity is suppressed -and made under authority of <tt/arpd/: - -<tscreen><verb> - arpd -b /var/tmp/arpd.db -a 3 -k eth0 eth1 -</verb></tscreen> - -This is mode which <tt/arpd/ is supposed to work normally. -It is not default just to prevent occasional enabling of too aggressive -mode occasionally. - -</enum> - -</article> - diff --git a/doc/do-psnup b/doc/do-psnup deleted file mode 100755 index 2dce848..0000000 --- a/doc/do-psnup +++ /dev/null @@ -1,16 +0,0 @@ -#! /bin/bash -# $1 = Temporary file . "string" -# $2 = File to process . "string" -# $3 = Page size . ie: a4 , letter ... "string" -# $4 = Number of pages to fit on a single sheet . "numeric" - -if type psnup >&/dev/null; then - echo "psnup -$4 -p$3 $1 $2" - psnup -$4 -p$3 $1 $2 -elif type psmulti >&/dev/null; then - echo "psmulti $1 > $2" - psmulti $1 > $2 -else - echo "cp $1 $2" - cp $1 $2 -fi diff --git a/doc/ip-cref.tex b/doc/ip-cref.tex deleted file mode 100644 index 5eaa4a8..0000000 --- a/doc/ip-cref.tex +++ /dev/null @@ -1,3316 +0,0 @@ -\documentstyle[12pt,twoside]{article} -\def\TITLE{IP Command Reference} -\input preamble -\begin{center} -\Large\bf IP Command Reference. -\end{center} - - -\begin{center} -{ \large Alexey~N.~Kuznetsov } \\ -\em Institute for Nuclear Research, Moscow \\ -\verb|kuznet@ms2.inr.ac.ru| \\ -\rm April 14, 1999 -\end{center} - -\vspace{5mm} - -\tableofcontents - -\newpage - -\section{About this document} - -This document presents a comprehensive description of the \verb|ip| utility -from the \verb|iproute2| package. It is not a tutorial or user's guide. -It is a {\em dictionary\/}, not explaining terms, -but translating them into other terms, which may also be unknown to the reader. -However, the document is self-contained and the reader, provided they have a -basic networking background, will find enough information -and examples to understand and configure Linux-2.2 IP and IPv6 -networking. - -This document is split into sections explaining \verb|ip| commands -and options, decrypting \verb|ip| output and containing a few examples. -More voluminous examples and some topics, which require more elaborate -discussion, are in the appendix. - -The paragraphs beginning with NB contain side notes, warnings about -bugs and design drawbacks. They may be skipped at the first reading. - -\section{{\tt ip} --- command syntax} - -The generic form of an \verb|ip| command is: -\begin{verbatim} -ip [ OPTIONS ] OBJECT [ COMMAND [ ARGUMENTS ]] -\end{verbatim} -where \verb|OPTIONS| is a set of optional modifiers affecting the -general behaviour of the \verb|ip| utility or changing its output. All options -begin with the character \verb|'-'| and may be used in either long or abbreviated -forms. Currently, the following options are available: - -\begin{itemize} -\item \verb|-V|, \verb|-Version| - ---- print the version of the \verb|ip| utility and exit. - - -\item \verb|-s|, \verb|-stats|, \verb|-statistics| - ---- output more information. If the option -appears twice or more, the amount of information increases. -As a rule, the information is statistics or some time values. - - -\item \verb|-f|, \verb|-family| followed by a protocol family -identifier: \verb|inet|, \verb|inet6| or \verb|link|. - ---- enforce the protocol family to use. If the option is not present, -the protocol family is guessed from other arguments. If the rest of the command -line does not give enough information to guess the family, \verb|ip| falls back to the default -one, usually \verb|inet| or \verb|any|. \verb|link| is a special family -identifier meaning that no networking protocol is involved. - -\item \verb|-4| - ---- shortcut for \verb|-family inet|. - -\item \verb|-6| - ---- shortcut for \verb|-family inet6|. - -\item \verb|-0| - ---- shortcut for \verb|-family link|. - - -\item \verb|-o|, \verb|-oneline| - ---- output each record on a single line, replacing line feeds -with the \verb|'\'| character. This is convenient when you want to -count records with \verb|wc| or to \verb|grep| the output. The trivial -script \verb|rtpr| converts the output back into readable form. - -\item \verb|-r|, \verb|-resolve| - ---- use the system's name resolver to print DNS names instead of -host addresses. - -\begin{NB} - Do not use this option when reporting bugs or asking for advice. -\end{NB} -\begin{NB} - \verb|ip| never uses DNS to resolve names to addresses. -\end{NB} - -\end{itemize} - -\verb|OBJECT| is the object to manage or to get information about. -The object types currently understood by \verb|ip| are: - -\begin{itemize} -\item \verb|link| --- network device -\item \verb|address| --- protocol (IP or IPv6) address on a device -\item \verb|neighbour| --- ARP or NDISC cache entry -\item \verb|route| --- routing table entry -\item \verb|rule| --- rule in routing policy database -\item \verb|maddress| --- multicast address -\item \verb|mroute| --- multicast routing cache entry -\item \verb|tunnel| --- tunnel over IP -\end{itemize} - -Again, the names of all objects may be written in full or -abbreviated form, f.e.\ \verb|address| is abbreviated as \verb|addr| -or just \verb|a|. - -\verb|COMMAND| specifies the action to perform on the object. -The set of possible actions depends on the object type. -As a rule, it is possible to \verb|add|, \verb|delete| and -\verb|show| (or \verb|list|) objects, but some objects -do not allow all of these operations or have some additional commands. -The \verb|help| command is available for all objects. It prints -out a list of available commands and argument syntax conventions. - -If no command is given, some default command is assumed. -Usually it is \verb|list| or, if the objects of this class -cannot be listed, \verb|help|. - -\verb|ARGUMENTS| is a list of arguments to the command. -The arguments depend on the command and object. There are two types of arguments: -{\em flags\/}, consisting of a single keyword, and {\em parameters\/}, -consisting of a keyword followed by a value. For convenience, -each command has some {\em default parameter\/} -which may be omitted. F.e.\ parameter \verb|dev| is the default -for the {\tt ip link} command, so {\tt ip link ls eth0} is equivalent -to {\tt ip link ls dev eth0}. -In the command descriptions below such parameters -are distinguished with the marker: ``(default)''. - -Almost all keywords may be abbreviated with several first (or even single) -letters. The shortcuts are convenient when \verb|ip| is used interactively, -but they are not recommended in scripts or when reporting bugs -or asking for advice. ``Officially'' allowed abbreviations are listed -in the document body. - - - -\section{{\tt ip} --- error messages} - -\verb|ip| may fail for one of the following reasons: - -\begin{itemize} -\item -A syntax error on the command line: an unknown keyword, incorrectly formatted -IP address {\em et al\/}. In this case \verb|ip| prints an error message -and exits. As a rule, the error message will contain information -about the reason for the failure. Sometimes it also prints a help page. - -\item -The arguments did not pass verification for self-consistency. - -\item -\verb|ip| failed to compile a kernel request from the arguments -because the user didn't give enough information. - -\item -The kernel returned an error to some syscall. In this case \verb|ip| -prints the error message, as it is output with \verb|perror(3)|, -prefixed with a comment and a syscall identifier. - -\item -The kernel returned an error to some RTNETLINK request. -In this case \verb|ip| prints the error message, as it is output -with \verb|perror(3)| prefixed with ``RTNETLINK answers:''. - -\end{itemize} - -All the operations are atomic, i.e.\ -if the \verb|ip| utility fails, it does not change anything -in the system. One harmful exception is \verb|ip link| command -(Sec.\ref{IP-LINK}, p.\pageref{IP-LINK}), -which may change only some of the device parameters given -on command line. - -It is difficult to list all the error messages (especially -syntax errors). However, as a rule, their meaning is clear -from the context of the command. - -The most common mistakes are: - -\begin{enumerate} -\item Netlink is not configured in the kernel. The message is: -\begin{verbatim} -Cannot open netlink socket: Invalid value -\end{verbatim} - -\item RTNETLINK is not configured in the kernel. In this case -one of the following messages may be printed, depending on the command: -\begin{verbatim} -Cannot talk to rtnetlink: Connection refused -Cannot send dump request: Connection refused -\end{verbatim} - -\item The \verb|CONFIG_IP_MULTIPLE_TABLES| option was not selected -when configuring the kernel. In this case any attempt to use the -\verb|ip| \verb|rule| command will fail, f.e. -\begin{verbatim} -kuznet@kaiser $ ip rule list -RTNETLINK error: Invalid argument -dump terminated -\end{verbatim} - -\end{enumerate} - - -\section{{\tt ip link} --- network device configuration} -\label{IP-LINK} - -\paragraph{Object:} A \verb|link| is a network device and the corresponding -commands display and change the state of devices. - -\paragraph{Commands:} \verb|set| and \verb|show| (or \verb|list|). - -\subsection{{\tt ip link set} --- change device attributes} - -\paragraph{Abbreviations:} \verb|set|, \verb|s|. - -\paragraph{Arguments:} - -\begin{itemize} -\item \verb|dev NAME| (default) - ---- \verb|NAME| specifies the network device on which to operate. - -\item \verb|up| and \verb|down| - ---- change the state of the device to \verb|UP| or \verb|DOWN|. - -\item \verb|arp on| or \verb|arp off| - ---- change the \verb|NOARP| flag on the device. - -\begin{NB} -This operation is {\em not allowed\/} if the device is in state \verb|UP|. -Though neither the \verb|ip| utility nor the kernel check for this condition. -You can get unpredictable results changing this flag while the -device is running. -\end{NB} - -\item \verb|multicast on| or \verb|multicast off| - ---- change the \verb|MULTICAST| flag on the device. - -\item \verb|dynamic on| or \verb|dynamic off| - ---- change the \verb|DYNAMIC| flag on the device. - -\item \verb|name NAME| - ---- change the name of the device. This operation is not -recommended if the device is running or has some addresses -already configured. - -\item \verb|txqueuelen NUMBER| or \verb|txqlen NUMBER| - ---- change the transmit queue length of the device. - -\item \verb|mtu NUMBER| - ---- change the MTU of the device. - -\item \verb|address LLADDRESS| - ---- change the station address of the interface. - -\item \verb|broadcast LLADDRESS|, \verb|brd LLADDRESS| or \verb|peer LLADDRESS| - ---- change the link layer broadcast address or the peer address when -the interface is \verb|POINTOPOINT|. - -\vskip 1mm -\begin{NB} -For most devices (f.e.\ for Ethernet) changing the link layer -broadcast address will break networking. -Do not use it, if you do not understand what this operation really does. -\end{NB} - -\end{itemize} - -\vskip 1mm -\begin{NB} -The {\tt ip} utility does not change the \verb|PROMISC| -or \verb|ALLMULTI| flags. These flags are considered -obsolete and should not be changed administratively. -\end{NB} - -\paragraph{Warning:} If multiple parameter changes are requested, -\verb|ip| aborts immediately after any of the changes have failed. -This is the only case when \verb|ip| can move the system to -an unpredictable state. The solution is to avoid changing -several parameters with one {\tt ip link set} call. - -\paragraph{Examples:} -\begin{itemize} -\item \verb|ip link set dummy address 00:00:00:00:00:01| - ---- change the station address of the interface \verb|dummy|. - -\item \verb|ip link set dummy up| - ---- start the interface \verb|dummy|. - -\end{itemize} - - -\subsection{{\tt ip link show} --- display device attributes} -\label{IP-LINK-SHOW} - -\paragraph{Abbreviations:} \verb|show|, \verb|list|, \verb|lst|, \verb|sh|, \verb|ls|, -\verb|l|. - -\paragraph{Arguments:} -\begin{itemize} -\item \verb|dev NAME| (default) - ---- \verb|NAME| specifies the network device to show. -If this argument is omitted all devices are listed. - -\item \verb|up| - ---- only display running interfaces. - -\end{itemize} - - -\paragraph{Output format:} - -\begin{verbatim} -kuznet@alisa:~ $ ip link ls eth0 -3: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc cbq qlen 100 - link/ether 00:a0:cc:66:18:78 brd ff:ff:ff:ff:ff:ff -kuznet@alisa:~ $ ip link ls sit0 -5: sit0@NONE: <NOARP,UP> mtu 1480 qdisc noqueue - link/sit 0.0.0.0 brd 0.0.0.0 -kuznet@alisa:~ $ ip link ls dummy -2: dummy: <BROADCAST,NOARP> mtu 1500 qdisc noop - link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff -kuznet@alisa:~ $ -\end{verbatim} - - -The number before each colon is an {\em interface index\/} or {\em ifindex\/}. -This number uniquely identifies the interface. This is followed by the {\em interface name\/} -(\verb|eth0|, \verb|sit0| etc.). The interface name is also -unique at every given moment. However, the interface may disappear from the -list (f.e.\ when the corresponding driver module is unloaded) and another -one with the same name may be created later. Besides that, -the administrator may change the name of any device with -\verb|ip| \verb|link| \verb|set| \verb|name| -to make it more intelligible. - -The interface name may have another name or \verb|NONE| appended -after the \verb|@| sign. This means that this device is bound to some other -device, -i.e.\ packets send through it are encapsulated and sent via the ``master'' -device. If the name is \verb|NONE|, the master is unknown. - -Then we see the interface {\em mtu\/} (``maximal transfer unit''). This determines -the maximal size of data which can be sent as a single packet over this interface. - -{\em qdisc\/} (``queuing discipline'') shows the queuing algorithm used -on the interface. Particularly, \verb|noqueue| means that this interface -does not queue anything and \verb|noop| means that the interface is in blackhole -mode i.e.\ all packets sent to it are immediately discarded. -{\em qlen\/} is the default transmit queue length of the device measured -in packets. - -The interface flags are summarized in the angle brackets. - -\begin{itemize} -\item \verb|UP| --- the device is turned on. It is ready to accept -packets for transmission and it may inject into the kernel packets received -from other nodes on the network. - -\item \verb|LOOPBACK| --- the interface does not communicate with other -hosts. All packets sent through it will be returned -and nothing but bounced packets can be received. - -\item \verb|BROADCAST| --- the device has the facility to send packets -to all hosts sharing the same link. A typical example is an Ethernet link. - -\item \verb|POINTOPOINT| --- the link has only two ends with one node -attached to each end. All packets sent to this link will reach the peer -and all packets received by us came from this single peer. - -If neither \verb|LOOPBACK| nor \verb|BROADCAST| nor \verb|POINTOPOINT| -are set, the interface is assumed to be NMBA (Non-Broadcast Multi-Access). -This is the most generic type of device and the most complicated one, because -the host attached to a NBMA link has no means to send to anyone -without additionally configured information. - -\item \verb|MULTICAST| --- is an advisory flag indicating that the interface -is aware of multicasting i.e.\ sending packets to some subset of neighbouring -nodes. Broadcasting is a particular case of multicasting, where the multicast -group consists of all nodes on the link. It is important to emphasize -that software {\em must not\/} interpret the absence of this flag as the inability -to use multicasting on this interface. Any \verb|POINTOPOINT| and -\verb|BROADCAST| link is multicasting by definition, because we have -direct access to all the neighbours and, hence, to any part of them. -Certainly, the use of high bandwidth multicast transfers is not recommended -on broadcast-only links because of high expense, but it is not strictly -prohibited. - -\item \verb|PROMISC| --- the device listens to and feeds to the kernel all -traffic on the link even if it is not destined for us, not broadcasted -and not destined for a multicast group of which we are member. Usually -this mode exists only on broadcast links and is used by bridges and for network -monitoring. - -\item \verb|ALLMULTI| --- the device receives all multicast packets -wandering on the link. This mode is used by multicast routers. - -\item \verb|NOARP| --- this flag is different from the other ones. It has -no invariant value and its interpretation depends on the network protocols -involved. As a rule, it indicates that the device needs no address -resolution and that the software or hardware knows how to deliver packets -without any help from the protocol stacks. - -\item \verb|DYNAMIC| --- is an advisory flag indicating that the interface is -dynamically created and destroyed. - -\item \verb|SLAVE| --- this interface is bonded to some other interfaces -to share link capacities. - -\end{itemize} - -\vskip 1mm -\begin{NB} -There are other flags but they are either obsolete (\verb|NOTRAILERS|) -or not implemented (\verb|DEBUG|) or specific to some devices -(\verb|MASTER|, \verb|AUTOMEDIA| and \verb|PORTSEL|). We do not discuss -them here. -\end{NB} -\begin{NB} -The values of \verb|PROMISC| and \verb|ALLMULTI| flags -shown by the \verb|ifconfig| utility and by the \verb|ip| utility -are {\em different\/}. \verb|ip link ls| shows the true device state, -while \verb|ifconfig| shows the virtual state which was set with -\verb|ifconfig| itself. -\end{NB} - - -The second line contains information on the link layer addresses -associated with the device. The first word (\verb|ether|, \verb|sit|) -defines the interface hardware type. This type determines the format and semantics -of the addresses and is logically part of the address. -The default format of the station address and the broadcast address -(or the peer address for pointopoint links) is a -sequence of hexadecimal bytes separated by colons, but some link -types may have their natural address format, f.e.\ addresses -of tunnels over IP are printed as dotted-quad IP addresses. - -\vskip 1mm -\begin{NB} - NBMA links have no well-defined broadcast or peer address, - however this field may contain useful information, f.e.\ - about the address of broadcast relay or about the address of the ARP server. -\end{NB} -\begin{NB} -Multicast addresses are not shown by this command, see -\verb|ip maddr ls| in~Sec.\ref{IP-MADDR} (p.\pageref{IP-MADDR} of this -document). -\end{NB} - - -\paragraph{Statistics:} With the \verb|-statistics| option, \verb|ip| also -prints interface statistics: - -\begin{verbatim} -kuznet@alisa:~ $ ip -s link ls eth0 -3: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc cbq qlen 100 - link/ether 00:a0:cc:66:18:78 brd ff:ff:ff:ff:ff:ff - RX: bytes packets errors dropped overrun mcast - 2449949362 2786187 0 0 0 0 - TX: bytes packets errors dropped carrier collsns - 178558497 1783945 332 0 332 35172 -kuznet@alisa:~ $ -\end{verbatim} -\verb|RX:| and \verb|TX:| lines summarize receiver and transmitter -statistics. They contain: -\begin{itemize} -\item \verb|bytes| --- the total number of bytes received or transmitted -on the interface. This number wraps when the maximal length of the data type -natural for the architecture is exceeded, so continuous monitoring requires -a user level daemon snapping it periodically. -\item \verb|packets| --- the total number of packets received or transmitted -on the interface. -\item \verb|errors| --- the total number of receiver or transmitter errors. -\item \verb|dropped| --- the total number of packets dropped due to lack -of resources. -\item \verb|overrun| --- the total number of receiver overruns resulting -in dropped packets. As a rule, if the interface is overrun, it means -serious problems in the kernel or that your machine is too slow -for this interface. -\item \verb|mcast| --- the total number of received multicast packets. This option -is only supported by a few devices. -\item \verb|carrier| --- total number of link media failures f.e.\ because -of lost carrier. -\item \verb|collsns| --- the total number of collision events -on Ethernet-like media. This number may have a different sense on other -link types. -\item \verb|compressed| --- the total number of compressed packets. This is -available only for links using VJ header compression. -\end{itemize} - - -If the \verb|-s| option is entered twice or more, -\verb|ip| prints more detailed statistics on receiver -and transmitter errors. - -\begin{verbatim} -kuznet@alisa:~ $ ip -s -s link ls eth0 -3: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc cbq qlen 100 - link/ether 00:a0:cc:66:18:78 brd ff:ff:ff:ff:ff:ff - RX: bytes packets errors dropped overrun mcast - 2449949362 2786187 0 0 0 0 - RX errors: length crc frame fifo missed - 0 0 0 0 0 - TX: bytes packets errors dropped carrier collsns - 178558497 1783945 332 0 332 35172 - TX errors: aborted fifo window heartbeat - 0 0 0 332 -kuznet@alisa:~ $ -\end{verbatim} -These error names are pure Ethernetisms. Other devices -may have non zero values in these fields but they may be -interpreted differently. - - -\section{{\tt ip address} --- protocol address management} - -\paragraph{Abbreviations:} \verb|address|, \verb|addr|, \verb|a|. - -\paragraph{Object:} The \verb|address| is a protocol (IP or IPv6) address attached -to a network device. Each device must have at least one address -to use the corresponding protocol. It is possible to have several -different addresses attached to one device. These addresses are not -discriminated, so that the term {\em alias\/} is not quite appropriate -for them and we do not use it in this document. - -The \verb|ip addr| command displays addresses and their properties, -adds new addresses and deletes old ones. - -\paragraph{Commands:} \verb|add|, \verb|delete|, \verb|flush| and \verb|show| -(or \verb|list|). - - -\subsection{{\tt ip address add} --- add a new protocol address} -\label{IP-ADDR-ADD} - -\paragraph{Abbreviations:} \verb|add|, \verb|a|. - -\paragraph{Arguments:} - -\begin{itemize} -\item \verb|dev NAME| - -\noindent--- the name of the device to add the address to. - -\item \verb|local ADDRESS| (default) - ---- the address of the interface. The format of the address depends -on the protocol. It is a dotted quad for IP and a sequence of hexadecimal halfwords -separated by colons for IPv6. The \verb|ADDRESS| may be followed by -a slash and a decimal number which encodes the network prefix length. - - -\item \verb|peer ADDRESS| - ---- the address of the remote endpoint for pointopoint interfaces. -Again, the \verb|ADDRESS| may be followed by a slash and a decimal number, -encoding the network prefix length. If a peer address is specified, -the local address {\em cannot\/} have a prefix length. The network prefix is associated -with the peer rather than with the local address. - - -\item \verb|broadcast ADDRESS| - ---- the broadcast address on the interface. - -It is possible to use the special symbols \verb|'+'| and \verb|'-'| -instead of the broadcast address. In this case, the broadcast address -is derived by setting/resetting the host bits of the interface prefix. - -\vskip 1mm -\begin{NB} -Unlike \verb|ifconfig|, the \verb|ip| utility {\em does not\/} set any broadcast -address unless explicitly requested. -\end{NB} - - -\item \verb|label NAME| - ---- Each address may be tagged with a label string. -In order to preserve compatibility with Linux-2.0 net aliases, -this string must coincide with the name of the device or must be prefixed -with the device name followed by colon. - - -\item \verb|scope SCOPE_VALUE| - ---- the scope of the area where this address is valid. -The available scopes are listed in file \verb|/etc/iproute2/rt_scopes|. -Predefined scope values are: - - \begin{itemize} - \item \verb|global| --- the address is globally valid. - \item \verb|site| --- (IPv6 only) the address is site local, - i.e.\ it is valid inside this site. - \item \verb|link| --- the address is link local, i.e.\ - it is valid only on this device. - \item \verb|host| --- the address is valid only inside this host. - \end{itemize} - -Appendix~\ref{ADDR-SEL} (p.\pageref{ADDR-SEL} of this document) -contains more details on address scopes. - -\end{itemize} - -\paragraph{Examples:} -\begin{itemize} -\item \verb|ip addr add 127.0.0.1/8 dev lo brd + scope host| - ---- add the usual loopback address to the loopback device. - -\item \verb|ip addr add 10.0.0.1/24 brd + dev eth0 label eth0:Alias| - ---- add the address 10.0.0.1 with prefix length 24 (i.e.\ netmask -\verb|255.255.255.0|), standard broadcast and label \verb|eth0:Alias| -to the interface \verb|eth0|. -\end{itemize} - - -\subsection{{\tt ip address delete} --- delete a protocol address} - -\paragraph{Abbreviations:} \verb|delete|, \verb|del|, \verb|d|. - -\paragraph{Arguments:} coincide with the arguments of \verb|ip addr add|. -The device name is a required argument. The rest are optional. -If no arguments are given, the first address is deleted. - -\paragraph{Examples:} -\begin{itemize} -\item \verb|ip addr del 127.0.0.1/8 dev lo| - ---- deletes the loopback address from the loopback device. -It would be best not to repeat this experiment. - -\item Disable IP on the interface \verb|eth0|: -\begin{verbatim} - while ip -f inet addr del dev eth0; do - : nothing - done -\end{verbatim} -Another method to disable IP on an interface using {\tt ip addr flush} -may be found in sec.\ref{IP-ADDR-FLUSH}, p.\pageref{IP-ADDR-FLUSH}. - -\end{itemize} - - -\subsection{{\tt ip address show} --- display protocol addresses} - -\paragraph{Abbreviations:} \verb|show|, \verb|list|, \verb|lst|, \verb|sh|, \verb|ls|, -\verb|l|. - -\paragraph{Arguments:} - -\begin{itemize} -\item \verb|dev NAME| (default) - ---- the name of the device. - -\item \verb|scope SCOPE_VAL| - ---- only list addresses with this scope. - -\item \verb|to PREFIX| - ---- only list addresses matching this prefix. - -\item \verb|label PATTERN| - ---- only list addresses with labels matching the \verb|PATTERN|. -\verb|PATTERN| is a usual shell style pattern. - - -\item \verb|dynamic| and \verb|permanent| - ---- (IPv6 only) only list addresses installed due to stateless -address configuration or only list permanent (not dynamic) addresses. - -\item \verb|tentative| - ---- (IPv6 only) only list addresses which did not pass duplicate -address detection. - -\item \verb|deprecated| - ---- (IPv6 only) only list deprecated addresses. - - -\item \verb|primary| and \verb|secondary| - ---- only list primary (or secondary) addresses. - -\end{itemize} - - -\paragraph{Output format:} - -\begin{verbatim} -kuznet@alisa:~ $ ip addr ls eth0 -3: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc cbq qlen 100 - link/ether 00:a0:cc:66:18:78 brd ff:ff:ff:ff:ff:ff - inet 193.233.7.90/24 brd 193.233.7.255 scope global eth0 - inet6 3ffe:2400:0:1:2a0:ccff:fe66:1878/64 scope global dynamic - valid_lft forever preferred_lft 604746sec - inet6 fe80::2a0:ccff:fe66:1878/10 scope link -kuznet@alisa:~ $ -\end{verbatim} - -The first two lines coincide with the output of \verb|ip link ls|. -It is natural to interpret link layer addresses -as addresses of the protocol family \verb|AF_PACKET|. - -Then the list of IP and IPv6 addresses follows, accompanied by -additional address attributes: scope value (see Sec.\ref{IP-ADDR-ADD}, -p.\pageref{IP-ADDR-ADD} above), flags and the address label. - -Address flags are set by the kernel and cannot be changed -administratively. Currently, the following flags are defined: - -\begin{enumerate} -\item \verb|secondary| - ---- the address is not used when selecting the default source address -of outgoing packets (Cf.\ Appendix~\ref{ADDR-SEL}, p.\pageref{ADDR-SEL}.). -An IP address becomes secondary if another address with the same -prefix bits already exists. The first address is primary. -It is the leader of the group of all secondary addresses. When the leader -is deleted, all secondaries are purged too. - - -\item \verb|dynamic| - ---- the address was created due to stateless autoconfiguration~\cite{RFC-ADDRCONF}. -In this case the output also contains information on times, when -the address is still valid. After \verb|preferred_lft| expires the address is -moved to the deprecated state. After \verb|valid_lft| expires the address -is finally invalidated. - -\item \verb|deprecated| - ---- the address is deprecated, i.e.\ it is still valid, but cannot -be used by newly created connections. - -\item \verb|tentative| - ---- the address is not used because duplicate address detection~\cite{RFC-ADDRCONF} -is still not complete or failed. - -\end{enumerate} - - -\subsection{{\tt ip address flush} --- flush protocol addresses} -\label{IP-ADDR-FLUSH} - -\paragraph{Abbreviations:} \verb|flush|, \verb|f|. - -\paragraph{Description:}This command flushes the protocol addresses -selected by some criteria. - -\paragraph{Arguments:} This command has the same arguments as \verb|show|. -The difference is that it does not run when no arguments are given. - -\paragraph{Warning:} This command (and other \verb|flush| commands -described below) is pretty dangerous. If you make a mistake, it will -not forgive it, but will cruelly purge all the addresses. - -\paragraph{Statistics:} With the \verb|-statistics| option, the command -becomes verbose. It prints out the number of deleted addresses and the number -of rounds made to flush the address list. If this option is given -twice, \verb|ip addr flush| also dumps all the deleted addresses -in the format described in the previous subsection. - -\paragraph{Example:} Delete all the addresses from the private network -10.0.0.0/8: -\begin{verbatim} -netadm@amber:~ # ip -s -s a f to 10/8 -2: dummy inet 10.7.7.7/16 brd 10.7.255.255 scope global dummy -3: eth0 inet 10.10.7.7/16 brd 10.10.255.255 scope global eth0 -4: eth1 inet 10.8.7.7/16 brd 10.8.255.255 scope global eth1 - -*** Round 1, deleting 3 addresses *** -*** Flush is complete after 1 round *** -netadm@amber:~ # -\end{verbatim} -Another instructive example is disabling IP on all the Ethernets: -\begin{verbatim} -netadm@amber:~ # ip -4 addr flush label "eth*" -\end{verbatim} -And the last example shows how to flush all the IPv6 addresses -acquired by the host from stateless address autoconfiguration -after you enabled forwarding or disabled autoconfiguration. -\begin{verbatim} -netadm@amber:~ # ip -6 addr flush dynamic -\end{verbatim} - - - -\section{{\tt ip neighbour} --- neighbour/arp tables management} - -\paragraph{Abbreviations:} \verb|neighbour|, \verb|neighbor|, \verb|neigh|, -\verb|n|. - -\paragraph{Object:} \verb|neighbour| objects establish bindings between protocol -addresses and link layer addresses for hosts sharing the same link. -Neighbour entries are organized into tables. The IPv4 neighbour table -is known by another name --- the ARP table. - -The corresponding commands display neighbour bindings -and their properties, add new neighbour entries and delete old ones. - -\paragraph{Commands:} \verb|add|, \verb|change|, \verb|replace|, -\verb|delete|, \verb|flush| and \verb|show| (or \verb|list|). - -\paragraph{See also:} Appendix~\ref{PROXY-NEIGH}, p.\pageref{PROXY-NEIGH} -describes how to manage proxy ARP/NDISC with the \verb|ip| utility. - - -\subsection{{\tt ip neighbour add} --- add a new neighbour entry\\ - {\tt ip neighbour change} --- change an existing entry\\ - {\tt ip neighbour replace} --- add a new entry or change an existing one} - -\paragraph{Abbreviations:} \verb|add|, \verb|a|; \verb|change|, \verb|chg|; -\verb|replace|, \verb|repl|. - -\paragraph{Description:} These commands create new neighbour records -or update existing ones. - -\paragraph{Arguments:} - -\begin{itemize} -\item \verb|to ADDRESS| (default) - ---- the protocol address of the neighbour. It is either an IPv4 or IPv6 address. - -\item \verb|dev NAME| - ---- the interface to which this neighbour is attached. - - -\item \verb|lladdr LLADDRESS| - ---- the link layer address of the neighbour. \verb|LLADDRESS| can also be -\verb|null|. - -\item \verb|nud NUD_STATE| - ---- the state of the neighbour entry. \verb|nud| is an abbreviation for ``Neighbour -Unreachability Detection''. The state can take one of the following values: - -\begin{enumerate} -\item \verb|permanent| --- the neighbour entry is valid forever and can be only be removed -administratively. -\item \verb|noarp| --- the neighbour entry is valid. No attempts to validate -this entry will be made but it can be removed when its lifetime expires. -\item \verb|reachable| --- the neighbour entry is valid until the reachability -timeout expires. -\item \verb|stale| --- the neighbour entry is valid but suspicious. -This option to \verb|ip neigh| does not change the neighbour state if -it was valid and the address is not changed by this command. -\end{enumerate} - -\end{itemize} - -\paragraph{Examples:} -\begin{itemize} -\item \verb|ip neigh add 10.0.0.3 lladdr 0:0:0:0:0:1 dev eth0 nud perm| - ---- add a permanent ARP entry for the neighbour 10.0.0.3 on the device \verb|eth0|. - -\item \verb|ip neigh chg 10.0.0.3 dev eth0 nud reachable| - ---- change its state to \verb|reachable|. -\end{itemize} - - -\subsection{{\tt ip neighbour delete} --- delete a neighbour entry} - -\paragraph{Abbreviations:} \verb|delete|, \verb|del|, \verb|d|. - -\paragraph{Description:} This command invalidates a neighbour entry. - -\paragraph{Arguments:} The arguments are the same as with \verb|ip neigh add|, -except that \verb|lladdr| and \verb|nud| are ignored. - - -\paragraph{Example:} -\begin{itemize} -\item \verb|ip neigh del 10.0.0.3 dev eth0| - ---- invalidate an ARP entry for the neighbour 10.0.0.3 on the device \verb|eth0|. - -\end{itemize} - -\begin{NB} - The deleted neighbour entry will not disappear from the tables - immediately. If it is in use it cannot be deleted until the last - client releases it. Otherwise it will be destroyed during - the next garbage collection. -\end{NB} - - -\paragraph{Warning:} Attempts to delete or manually change -a \verb|noarp| entry created by the kernel may result in unpredictable behaviour. -Particularly, the kernel may try to resolve this address even -on a \verb|NOARP| interface or if the address is multicast or broadcast. - - -\subsection{{\tt ip neighbour show} --- list neighbour entries} - -\paragraph{Abbreviations:} \verb|show|, \verb|list|, \verb|sh|, \verb|ls|. - -\paragraph{Description:}This commands displays neighbour tables. - -\paragraph{Arguments:} - -\begin{itemize} - -\item \verb|to ADDRESS| (default) - ---- the prefix selecting the neighbours to list. - -\item \verb|dev NAME| - ---- only list the neighbours attached to this device. - -\item \verb|unused| - ---- only list neighbours which are not currently in use. - -\item \verb|nud NUD_STATE| - ---- only list neighbour entries in this state. \verb|NUD_STATE| takes -values listed below or the special value \verb|all| which means all states. -This option may occur more than once. If this option is absent, \verb|ip| -lists all entries except for \verb|none| and \verb|noarp|. - -\end{itemize} - - -\paragraph{Output format:} - -\begin{verbatim} -kuznet@alisa:~ $ ip neigh ls -:: dev lo lladdr 00:00:00:00:00:00 nud noarp -fe80::200:cff:fe76:3f85 dev eth0 lladdr 00:00:0c:76:3f:85 router \ - nud stale -0.0.0.0 dev lo lladdr 00:00:00:00:00:00 nud noarp -193.233.7.254 dev eth0 lladdr 00:00:0c:76:3f:85 nud reachable -193.233.7.85 dev eth0 lladdr 00:e0:1e:63:39:00 nud stale -kuznet@alisa:~ $ -\end{verbatim} - -The first word of each line is the protocol address of the neighbour. -Then the device name follows. The rest of the line describes the contents of -the neighbour entry identified by the pair (device, address). - -\verb|lladdr| is the link layer address of the neighbour. - -\verb|nud| is the state of the ``neighbour unreachability detection'' machine -for this entry. The detailed description of the neighbour -state machine can be found in~\cite{RFC-NDISC}. Here is the full list -of the states with short descriptions: - -\begin{enumerate} -\item\verb|none| --- the state of the neighbour is void. -\item\verb|incomplete| --- the neighbour is in the process of resolution. -\item\verb|reachable| --- the neighbour is valid and apparently reachable. -\item\verb|stale| --- the neighbour is valid, but is probably already -unreachable, so the kernel will try to check it at the first transmission. -\item\verb|delay| --- a packet has been sent to the stale neighbour and the kernel is waiting -for confirmation. -\item\verb|probe| --- the delay timer expired but no confirmation was received. -The kernel has started to probe the neighbour with ARP/NDISC messages. -\item\verb|failed| --- resolution has failed. -\item\verb|noarp| --- the neighbour is valid. No attempts to check the entry -will be made. -\item\verb|permanent| --- it is a \verb|noarp| entry, but only the administrator -may remove the entry from the neighbour table. -\end{enumerate} - -The link layer address is valid in all states except for \verb|none|, -\verb|failed| and \verb|incomplete|. - -IPv6 neighbours can be marked with the additional flag \verb|router| -which means that the neighbour introduced itself as an IPv6 router~\cite{RFC-NDISC}. - -\paragraph{Statistics:} The \verb|-statistics| option displays some usage -statistics, f.e.\ - -\begin{verbatim} -kuznet@alisa:~ $ ip -s n ls 193.233.7.254 -193.233.7.254 dev eth0 lladdr 00:00:0c:76:3f:85 ref 5 used 12/13/20 \ - nud reachable -kuznet@alisa:~ $ -\end{verbatim} - -Here \verb|ref| is the number of users of this entry -and \verb|used| is a triplet of time intervals in seconds -separated by slashes. In this case they show that: - -\begin{enumerate} -\item the entry was used 12 seconds ago. -\item the entry was confirmed 13 seconds ago. -\item the entry was updated 20 seconds ago. -\end{enumerate} - -\subsection{{\tt ip neighbour flush} --- flush neighbour entries} - -\paragraph{Abbreviations:} \verb|flush|, \verb|f|. - -\paragraph{Description:}This command flushes neighbour tables, selecting -entries to flush by some criteria. - -\paragraph{Arguments:} This command has the same arguments as \verb|show|. -The differences are that it does not run when no arguments are given, -and that the default neighbour states to be flushed do not include -\verb|permanent| and \verb|noarp|. - - -\paragraph{Statistics:} With the \verb|-statistics| option, the command -becomes verbose. It prints out the number of deleted neighbours and the number -of rounds made to flush the neighbour table. If the option is given -twice, \verb|ip neigh flush| also dumps all the deleted neighbours -in the format described in the previous subsection. - -\paragraph{Example:} -\begin{verbatim} -netadm@alisa:~ # ip -s -s n f 193.233.7.254 -193.233.7.254 dev eth0 lladdr 00:00:0c:76:3f:85 ref 5 used 12/13/20 \ - nud reachable - -*** Round 1, deleting 1 entries *** -*** Flush is complete after 1 round *** -netadm@alisa:~ # -\end{verbatim} - - -\section{{\tt ip route} --- routing table management} -\label{IP-ROUTE} - -\paragraph{Abbreviations:} \verb|route|, \verb|ro|, \verb|r|. - -\paragraph{Object:} \verb|route| entries in the kernel routing tables keep -information about paths to other networked nodes. - -Each route entry has a {\em key\/} consisting of a {\em prefix\/} -(i.e.\ a pair containing a network address and the length of its mask) and, -optionally, the TOS value. An IP packet matches the route if the highest -bits of its destination address are equal to the route prefix at least -up to the prefix length and if the TOS of the route is zero or equal to -the TOS of the packet. - -If several routes match the packet, the following pruning rules -are used to select the best one (see~\cite{RFC1812}): -\begin{enumerate} -\item The longest matching prefix is selected. All shorter ones -are dropped. - -\item If the TOS of some route with the longest prefix is equal to the TOS -of the packet, the routes with different TOS are dropped. - -If no exact TOS match was found and routes with TOS=0 exist, -the rest of routes are pruned. - -Otherwise, the route lookup fails. - -\item If several routes remain after the previous steps, then -the routes with the best preference values are selected. - -\item If we still have several routes, then the {\em first\/} of them -is selected. - -\begin{NB} - Note the ambiguity of the last step. Unfortunately, Linux - historically allows such a bizarre situation. The sense of the -word ``first'' depends on the order of route additions and it is practically -impossible to maintain a bundle of such routes in this order. -\end{NB} - -For simplicity we will limit ourselves to the case where such a situation -is impossible and routes are uniquely identified by the triplet -\{prefix, tos, preference\}. Actually, it is impossible to create -non-unique routes with \verb|ip| commands described in this section. - -One useful exception to this rule is the default route on non-forwarding -hosts. It is ``officially'' allowed to have several fallback routes -when several routers are present on directly connected networks. -In this case, Linux-2.2 makes ``dead gateway detection''~\cite{RFC1122} -controlled by neighbour unreachability detection and by advice -from transport protocols to select a working router, so the order -of the routes is not essential. However, in this case, -fiddling with default routes manually is not recommended. Use the Router Discovery -protocol (see Appendix~\ref{EXAMPLE-SETUP}, p.\pageref{EXAMPLE-SETUP}) -instead. Actually, Linux-2.2 IPv6 does not give user level applications -any access to default routes. -\end{enumerate} - -Certainly, the steps above are not performed exactly -in this sequence. Instead, the routing table in the kernel is kept -in some data structure to achieve the final result -with minimal cost. However, not depending on a particular -routing algorithm implemented in the kernel, we can summarize -the statements above as: a route is identified by the triplet -\{prefix, tos, preference\}. This {\em key\/} lets us locate -the route in the routing table. - -\paragraph{Route attributes:} Each route key refers to a routing -information record containing -the data required to deliver IP packets (f.e.\ output device and -next hop router) and some optional attributes (f.e. the path MTU or -the preferred source address when communicating with this destination). -These attributes are described in the following subsection. - -\paragraph{Route types:} \label{IP-ROUTE-TYPES} -It is important that the set -of required and optional attributes depend on the route {\em type\/}. -The most important route type -is \verb|unicast|. It describes real paths to other hosts. -As a rule, common routing tables contain only such routes. However, -there are other types of routes with different semantics. The -full list of types understood by Linux-2.2 is: -\begin{itemize} -\item \verb|unicast| --- the route entry describes real paths to the -destinations covered by the route prefix. -\item \verb|unreachable| --- these destinations are unreachable. Packets -are discarded and the ICMP message {\em host unreachable\/} is generated. -The local senders get an \verb|EHOSTUNREACH| error. -\item \verb|blackhole| --- these destinations are unreachable. Packets -are discarded silently. The local senders get an \verb|EINVAL| error. -\item \verb|prohibit| --- these destinations are unreachable. Packets -are discarded and the ICMP message {\em communication administratively -prohibited\/} is generated. The local senders get an \verb|EACCES| error. -\item \verb|local| --- the destinations are assigned to this -host. The packets are looped back and delivered locally. -\item \verb|broadcast| --- the destinations are broadcast addresses. -The packets are sent as link broadcasts. -\item \verb|throw| --- a special control route used together with policy -rules (see sec.\ref{IP-RULE}, p.\pageref{IP-RULE}). If such a route is selected, lookup -in this table is terminated pretending that no route was found. -Without policy routing it is equivalent to the absence of the route in the routing -table. The packets are dropped and the ICMP message {\em net unreachable\/} -is generated. The local senders get an \verb|ENETUNREACH| error. -\item \verb|nat| --- a special NAT route. Destinations covered by the prefix -are considered to be dummy (or external) addresses which require translation -to real (or internal) ones before forwarding. The addresses to translate to -are selected with the attribute \verb|via|. More about NAT is -in Appendix~\ref{ROUTE-NAT}, p.\pageref{ROUTE-NAT}. -\item \verb|anycast| --- ({\em not implemented\/}) the destinations are -{\em anycast\/} addresses assigned to this host. They are mainly equivalent -to \verb|local| with one difference: such addresses are invalid when used -as the source address of any packet. -\item \verb|multicast| --- a special type used for multicast routing. -It is not present in normal routing tables. -\end{itemize} - -\paragraph{Route tables:} Linux-2.2 can pack routes into several routing -tables identified by a number in the range from 1 to 255 or by -name from the file \verb|/etc/iproute2/rt_tables|. By default all normal -routes are inserted into the \verb|main| table (ID 254) and the kernel only uses -this table when calculating routes. - -Actually, one other table always exists, which is invisible but -even more important. It is the \verb|local| table (ID 255). This table -consists of routes for local and broadcast addresses. The kernel maintains -this table automatically and the administrator usually need not modify it -or even look at it. - -The multiple routing tables enter the game when {\em policy routing\/} -is used. See sec.\ref{IP-RULE}, p.\pageref{IP-RULE}. -In this case, the table identifier effectively becomes -one more parameter, which should be added to the triplet -\{prefix, tos, preference\} to uniquely identify the route. - - -\subsection{{\tt ip route add} --- add a new route\\ - {\tt ip route change} --- change a route\\ - {\tt ip route replace} --- change a route or add a new one} -\label{IP-ROUTE-ADD} - -\paragraph{Abbreviations:} \verb|add|, \verb|a|; \verb|change|, \verb|chg|; - \verb|replace|, \verb|repl|. - - -\paragraph{Arguments:} -\begin{itemize} -\item \verb|to PREFIX| or \verb|to TYPE PREFIX| (default) - ---- the destination prefix of the route. If \verb|TYPE| is omitted, -\verb|ip| assumes type \verb|unicast|. Other values of \verb|TYPE| -are listed above. \verb|PREFIX| is an IP or IPv6 address optionally followed -by a slash and the prefix length. If the length of the prefix is missing, -\verb|ip| assumes a full-length host route. There is also a special -\verb|PREFIX| --- \verb|default| --- which is equivalent to IP \verb|0/0| or -to IPv6 \verb|::/0|. - -\item \verb|tos TOS| or \verb|dsfield TOS| - ---- the Type Of Service (TOS) key. This key has no associated mask and -the longest match is understood as: First, compare the TOS -of the route and of the packet. If they are not equal, then the packet -may still match a route with a zero TOS. \verb|TOS| is either an 8 bit hexadecimal -number or an identifier from {\tt /etc/iproute2/rt\_dsfield}. - - -\item \verb|metric NUMBER| or \verb|preference NUMBER| - ---- the preference value of the route. \verb|NUMBER| is an arbitrary 32bit number. - -\item \verb|table TABLEID| - ---- the table to add this route to. -\verb|TABLEID| may be a number or a string from the file -\verb|/etc/iproute2/rt_tables|. If this parameter is omitted, -\verb|ip| assumes the \verb|main| table, with the exception of -\verb|local|, \verb|broadcast| and \verb|nat| routes, which are -put into the \verb|local| table by default. - -\item \verb|dev NAME| - ---- the output device name. - -\item \verb|via ADDRESS| - ---- the address of the nexthop router. Actually, the sense of this field depends -on the route type. For normal \verb|unicast| routes it is either the true nexthop -router or, if it is a direct route installed in BSD compatibility mode, -it can be a local address of the interface. -For NAT routes it is the first address of the block of translated IP destinations. - -\item \verb|src ADDRESS| - ---- the source address to prefer when sending to the destinations -covered by the route prefix. - -\item \verb|realm REALMID| - ---- the realm to which this route is assigned. -\verb|REALMID| may be a number or a string from the file -\verb|/etc/iproute2/rt_realms|. Sec.\ref{RT-REALMS} (p.\pageref{RT-REALMS}) -contains more information on realms. - -\item \verb|mtu MTU| or \verb|mtu lock MTU| - ---- the MTU along the path to the destination. If the modifier \verb|lock| is -not used, the MTU may be updated by the kernel due to Path MTU Discovery. -If the modifier \verb|lock| is used, no path MTU discovery will be tried, -all packets will be sent without the DF bit in IPv4 case -or fragmented to MTU for IPv6. - -\item \verb|window NUMBER| - ---- the maximal window for TCP to advertise to these destinations, -measured in bytes. It limits maximal data bursts that our TCP -peers are allowed to send to us. - -\item \verb|rtt NUMBER| - ---- the initial RTT (``Round Trip Time'') estimate. - - -\item \verb|rttvar NUMBER| - ---- \threeonly the initial RTT variance estimate. - - -\item \verb|ssthresh NUMBER| - ---- \threeonly an estimate for the initial slow start threshold. - - -\item \verb|cwnd NUMBER| - ---- \threeonly the clamp for congestion window. It is ignored if the \verb|lock| - flag is not used. - - -\item \verb|advmss NUMBER| - ---- \threeonly the MSS (``Maximal Segment Size'') to advertise to these - destinations when establishing TCP connections. If it is not given, - Linux uses a default value calculated from the first hop device MTU. - -\begin{NB} - If the path to these destination is asymmetric, this guess may be wrong. -\end{NB} - -\item \verb|reordering NUMBER| - ---- \threeonly Maximal reordering on the path to this destination. - If it is not given, Linux uses the value selected with \verb|sysctl| - variable \verb|net/ipv4/tcp_reordering|. - - - -\item \verb|nexthop NEXTHOP| - ---- the nexthop of a multipath route. \verb|NEXTHOP| is a complex value -with its own syntax similar to the top level argument lists: -\begin{itemize} -\item \verb|via ADDRESS| is the nexthop router. -\item \verb|dev NAME| is the output device. -\item \verb|weight NUMBER| is a weight for this element of a multipath -route reflecting its relative bandwidth or quality. -\end{itemize} - -\item \verb|scope SCOPE_VAL| - ---- the scope of the destinations covered by the route prefix. -\verb|SCOPE_VAL| may be a number or a string from the file -\verb|/etc/iproute2/rt_scopes|. -If this parameter is omitted, -\verb|ip| assumes scope \verb|global| for all gatewayed \verb|unicast| -routes, scope \verb|link| for direct \verb|unicast| and \verb|broadcast| routes -and scope \verb|host| for \verb|local| routes. - -\item \verb|protocol RTPROTO| - ---- the routing protocol identifier of this route. -\verb|RTPROTO| may be a number or a string from the file -\verb|/etc/iproute2/rt_protos|. If the routing protocol ID is -not given, \verb|ip| assumes protocol \verb|boot| (i.e.\ -it assumes the route was added by someone who doesn't -understand what they are doing). Several protocol values have a fixed interpretation. -Namely: -\begin{itemize} -\item \verb|redirect| --- the route was installed due to an ICMP redirect. -\item \verb|kernel| --- the route was installed by the kernel during -autoconfiguration. -\item \verb|boot| --- the route was installed during the bootup sequence. -If a routing daemon starts, it will purge all of them. -\item \verb|static| --- the route was installed by the administrator -to override dynamic routing. Routing daemon will respect them -and, probably, even advertise them to its peers. -\item \verb|ra| --- the route was installed by Router Discovery protocol. -\end{itemize} -The rest of the values are not reserved and the administrator is free -to assign (or not to assign) protocol tags. At least, routing -daemons should take care of setting some unique protocol values, -f.e.\ as they are assigned in \verb|rtnetlink.h| or in \verb|rt_protos| -database. - - -\item \verb|onlink| - ---- pretend that the nexthop is directly attached to this link, -even if it does not match any interface prefix. One application of this -option may be found in~\cite{IP-TUNNELS}. - -\item \verb|equalize| - ---- allow packet by packet randomization on multipath routes. -Without this modifier, the route will be frozen to one selected -nexthop, so that load splitting will only occur on per-flow base. -\verb|equalize| only works if the kernel is patched. - - -\end{itemize} - - -\begin{NB} - Actually there are more commands: \verb|prepend| does the same - thing as classic \verb|route add|, i.e.\ adds a route, even if another - route to the same destination exists. Its opposite case is \verb|append|, - which adds the route to the end of the list. Avoid these - features. -\end{NB} -\begin{NB} - More sad news, IPv6 only understands the \verb|append| command correctly. - All the others are translated into \verb|append| commands. Certainly, - this will change in the future. -\end{NB} - -\paragraph{Examples:} -\begin{itemize} -\item add a plain route to network 10.0.0/24 via gateway 193.233.7.65 -\begin{verbatim} - ip route add 10.0.0/24 via 193.233.7.65 -\end{verbatim} -\item change it to a direct route via the \verb|dummy| device -\begin{verbatim} - ip ro chg 10.0.0/24 dev dummy -\end{verbatim} -\item add a default multipath route splitting the load between \verb|ppp0| -and \verb|ppp1| -\begin{verbatim} - ip route add default scope global nexthop dev ppp0 \ - nexthop dev ppp1 -\end{verbatim} -Note the scope value. It is not necessary but it informs the kernel -that this route is gatewayed rather than direct. Actually, if you -know the addresses of remote endpoints it would be better to use the -\verb|via| parameter. -\item announce that the address 192.203.80.144 is not a real one, but -should be translated to 193.233.7.83 before forwarding -\begin{verbatim} - ip route add nat 192.203.80.144 via 193.233.7.83 -\end{verbatim} -Backward translation is setup with policy rules described -in the following section (sec.\ref{IP-RULE}, p.\pageref{IP-RULE}). -\end{itemize} - -\subsection{{\tt ip route delete} --- delete a route} - -\paragraph{Abbreviations:} \verb|delete|, \verb|del|, \verb|d|. - -\paragraph{Arguments:} \verb|ip route del| has the same arguments as -\verb|ip route add|, but their semantics are a bit different. - -Key values (\verb|to|, \verb|tos|, \verb|preference| and \verb|table|) -select the route to delete. If optional attributes are present, \verb|ip| -verifies that they coincide with the attributes of the route to delete. -If no route with the given key and attributes was found, \verb|ip route del| -fails. -\begin{NB} -Linux-2.0 had the option to delete a route selected only by prefix address, -ignoring its length (i.e.\ netmask). This option no longer exists -because it was ambiguous. However, look at {\tt ip route flush} -(sec.\ref{IP-ROUTE-FLUSH}, p.\pageref{IP-ROUTE-FLUSH}) which -provides similar and even richer functionality. -\end{NB} - -\paragraph{Example:} -\begin{itemize} -\item delete the multipath route created by the command in previous subsection -\begin{verbatim} - ip route del default scope global nexthop dev ppp0 \ - nexthop dev ppp1 -\end{verbatim} -\end{itemize} - - - -\subsection{{\tt ip route show} --- list routes} - -\paragraph{Abbreviations:} \verb|show|, \verb|list|, \verb|sh|, \verb|ls|, \verb|l|. - -\paragraph{Description:} the command displays the contents of the routing tables -or the route(s) selected by some criteria. - - -\paragraph{Arguments:} -\begin{itemize} -\item \verb|to SELECTOR| (default) - ---- only select routes from the given range of destinations. \verb|SELECTOR| -consists of an optional modifier (\verb|root|, \verb|match| or \verb|exact|) -and a prefix. \verb|root PREFIX| selects routes with prefixes not shorter -than \verb|PREFIX|. F.e.\ \verb|root 0/0| selects the entire routing table. -\verb|match PREFIX| selects routes with prefixes not longer than -\verb|PREFIX|. F.e.\ \verb|match 10.0/16| selects \verb|10.0/16|, -\verb|10/8| and \verb|0/0|, but it does not select \verb|10.1/16| and -\verb|10.0.0/24|. And \verb|exact PREFIX| (or just \verb|PREFIX|) -selects routes with this exact prefix. If neither of these options -are present, \verb|ip| assumes \verb|root 0/0| i.e.\ it lists the entire table. - - -\item \verb|tos TOS| or \verb|dsfield TOS| - - --- only select routes with the given TOS. - - -\item \verb|table TABLEID| - - --- show the routes from this table(s). The default setting is to show -\verb|table| \verb|main|. \verb|TABLEID| may either be the ID of a real table -or one of the special values: - \begin{itemize} - \item \verb|all| --- list all of the tables. - \item \verb|cache| --- dump the routing cache. - \end{itemize} -\begin{NB} - IPv6 has a single table. However, splitting it into \verb|main|, \verb|local| - and \verb|cache| is emulated by the \verb|ip| utility. -\end{NB} - -\item \verb|cloned| or \verb|cached| - ---- list cloned routes i.e.\ routes which were dynamically forked from -other routes because some route attribute (f.e.\ MTU) was updated. -Actually, it is equivalent to \verb|table cache|. - -\item \verb|from SELECTOR| - ---- the same syntax as for \verb|to|, but it binds the source address range -rather than destinations. Note that the \verb|from| option only works with -cloned routes. - -\item \verb|protocol RTPROTO| - ---- only list routes of this protocol. - - -\item \verb|scope SCOPE_VAL| - ---- only list routes with this scope. - -\item \verb|type TYPE| - ---- only list routes of this type. - -\item \verb|dev NAME| - ---- only list routes going via this device. - -\item \verb|via PREFIX| - ---- only list routes going via the nexthop routers selected by \verb|PREFIX|. - -\item \verb|src PREFIX| - ---- only list routes with preferred source addresses selected -by \verb|PREFIX|. - -\item \verb|realm REALMID| or \verb|realms FROMREALM/TOREALM| - ---- only list routes with these realms. - -\end{itemize} - -\paragraph{Examples:} Let us count routes of protocol \verb|gated/bgp| -on a router: -\begin{verbatim} -kuznet@amber:~ $ ip ro ls proto gated/bgp | wc - 1413 9891 79010 -kuznet@amber:~ $ -\end{verbatim} -To count the size of the routing cache, we have to use the \verb|-o| option -because cached attributes can take more than one line of output: -\begin{verbatim} -kuznet@amber:~ $ ip -o ro ls cloned | wc - 159 2543 18707 -kuznet@amber:~ $ -\end{verbatim} - - -\paragraph{Output format:} The output of this command consists -of per route records separated by line feeds. -However, some records may consist -of more than one line: particularly, this is the case when the route -is cloned or you requested additional statistics. If the -\verb|-o| option was given, then line feeds separating lines inside -records are replaced with the backslash sign. - -The output has the same syntax as arguments given to {\tt ip route add}, -so that it can be understood easily. F.e.\ -\begin{verbatim} -kuznet@amber:~ $ ip ro ls 193.233.7/24 -193.233.7.0/24 dev eth0 proto gated/conn scope link \ - src 193.233.7.65 realms inr.ac -kuznet@amber:~ $ -\end{verbatim} - -If you list cloned entries, the output contains other attributes which -are evaluated during route calculation and updated during route -lifetime. An example of the output is: -\begin{verbatim} -kuznet@amber:~ $ ip ro ls 193.233.7.82 tab cache -193.233.7.82 from 193.233.7.82 dev eth0 src 193.233.7.65 \ - realms inr.ac/inr.ac - cache <src-direct,redirect> mtu 1500 rtt 300 iif eth0 -193.233.7.82 dev eth0 src 193.233.7.65 realms inr.ac - cache mtu 1500 rtt 300 -kuznet@amber:~ $ -\end{verbatim} -\begin{NB} - \label{NB-strange-route} - The route looks a bit strange, doesn't it? Did you notice that - it is a path from 193.233.7.82 back to 193.233.82? Well, you will - see in the section on \verb|ip route get| (p.\pageref{NB-nature-of-strangeness}) - how it appeared. -\end{NB} -The second line, starting with the word \verb|cache|, shows -additional attributes which normal routes do not possess. -Cached flags are summarized in angle brackets: -\begin{itemize} -\item \verb|local| --- packets are delivered locally. -It stands for loopback unicast routes, for broadcast routes -and for multicast routes, if this host is a member of the corresponding -group. - -\item \verb|reject| --- the path is bad. Any attempt to use it results -in an error. See attribute \verb|error| below (p.\pageref{IP-ROUTE-GET-error}). - -\item \verb|mc| --- the destination is multicast. - -\item \verb|brd| --- the destination is broadcast. - -\item \verb|src-direct| --- the source is on a directly connected -interface. - -\item \verb|redirected| --- the route was created by an ICMP Redirect. - -\item \verb|redirect| --- packets going via this route will -trigger an ICMP redirect. - -\item \verb|fastroute| --- the route is eligible to be used for fastroute. - -\item \verb|equalize| --- make packet by packet randomization -along this path. - -\item \verb|dst-nat| --- the destination address requires translation. - -\item \verb|src-nat| --- the source address requires translation. - -\item \verb|masq| --- the source address requires masquerading. -This feature disappeared in linux-2.4. - -\item \verb|notify| --- ({\em not implemented}) change/deletion -of this route will trigger RTNETLINK notification. -\end{itemize} - -Then some optional attributes follow: -\begin{itemize} -\item \verb|error| --- on \verb|reject| routes it is error code -returned to local senders when they try to use this route. -These error codes are translated into ICMP error codes, sent to remote -senders, according to the rules described above in the subsection -devoted to route types (p.\pageref{IP-ROUTE-TYPES}). -\label{IP-ROUTE-GET-error} - -\item \verb|expires| --- this entry will expire after this timeout. - -\item \verb|iif| --- the packets for this path are expected to arrive -on this interface. -\end{itemize} - -\paragraph{Statistics:} With the \verb|-statistics| option, more -information about this route is shown: -\begin{itemize} -\item \verb|users| --- the number of users of this entry. -\item \verb|age| --- shows when this route was last used. -\item \verb|used| --- the number of lookups of this route since its creation. -\end{itemize} - - -\subsection{{\tt ip route flush} --- flush routing tables} -\label{IP-ROUTE-FLUSH} - -\paragraph{Abbreviations:} \verb|flush|, \verb|f|. - -\paragraph{Description:} this command flushes routes selected -by some criteria. - -\paragraph{Arguments:} the arguments have the same syntax and semantics -as the arguments of \verb|ip route show|, but routing tables are not -listed but purged. The only difference is the default action: \verb|show| -dumps all the IP main routing table but \verb|flush| prints the helper page. -The reason for this difference does not require any explanation, does it? - - -\paragraph{Statistics:} With the \verb|-statistics| option, the command -becomes verbose. It prints out the number of deleted routes and the number -of rounds made to flush the routing table. If the option is given -twice, \verb|ip route flush| also dumps all the deleted routes -in the format described in the previous subsection. - -\paragraph{Examples:} The first example flushes all the -gatewayed routes from the main table (f.e.\ after a routing daemon crash). -\begin{verbatim} -netadm@amber:~ # ip -4 ro flush scope global type unicast -\end{verbatim} -This option deserves to be put into a scriptlet \verb|routef|. -\begin{NB} -This option was described in the \verb|route(8)| man page borrowed -from BSD, but was never implemented in Linux. -\end{NB} - -The second example flushes all IPv6 cloned routes: -\begin{verbatim} -netadm@amber:~ # ip -6 -s -s ro flush cache -3ffe:2400::220:afff:fef4:c5d1 via 3ffe:2400::220:afff:fef4:c5d1 \ - dev eth0 metric 0 - cache used 2 age 12sec mtu 1500 rtt 300 -3ffe:2400::280:adff:feb7:8034 via 3ffe:2400::280:adff:feb7:8034 \ - dev eth0 metric 0 - cache used 2 age 15sec mtu 1500 rtt 300 -3ffe:2400::280:c8ff:fe59:5bcc via 3ffe:2400::280:c8ff:fe59:5bcc \ - dev eth0 metric 0 - cache users 1 used 1 age 23sec mtu 1500 rtt 300 -3ffe:2400:0:1:2a0:ccff:fe66:1878 via 3ffe:2400:0:1:2a0:ccff:fe66:1878 \ - dev eth1 metric 0 - cache used 2 age 20sec mtu 1500 rtt 300 -3ffe:2400:0:1:a00:20ff:fe71:fb30 via 3ffe:2400:0:1:a00:20ff:fe71:fb30 \ - dev eth1 metric 0 - cache used 2 age 33sec mtu 1500 rtt 300 -ff02::1 via ff02::1 dev eth1 metric 0 - cache users 1 used 1 age 45sec mtu 1500 rtt 300 - -*** Round 1, deleting 6 entries *** -*** Flush is complete after 1 round *** -netadm@amber:~ # ip -6 -s -s ro flush cache -Nothing to flush. -netadm@amber:~ # -\end{verbatim} - -The third example flushes BGP routing tables after a \verb|gated| -death. -\begin{verbatim} -netadm@amber:~ # ip ro ls proto gated/bgp | wc - 1408 9856 78730 -netadm@amber:~ # ip -s ro f proto gated/bgp - -*** Round 1, deleting 1408 entries *** -*** Flush is complete after 1 round *** -netadm@amber:~ # ip ro f proto gated/bgp -Nothing to flush. -netadm@amber:~ # ip ro ls proto gated/bgp -netadm@amber:~ # -\end{verbatim} - - -\subsection{{\tt ip route get} --- get a single route} -\label{IP-ROUTE-GET} - -\paragraph{Abbreviations:} \verb|get|, \verb|g|. - -\paragraph{Description:} this command gets a single route to a destination -and prints its contents exactly as the kernel sees it. - -\paragraph{Arguments:} -\begin{itemize} -\item \verb|to ADDRESS| (default) - ---- the destination address. - -\item \verb|from ADDRESS| - ---- the source address. - -\item \verb|tos TOS| or \verb|dsfield TOS| - ---- the Type Of Service. - -\item \verb|iif NAME| - ---- the device from which this packet is expected to arrive. - -\item \verb|oif NAME| - ---- force the output device on which this packet will be routed. - -\item \verb|connected| - ---- if no source address (option \verb|from|) was given, relookup -the route with the source set to the preferred address received from the first lookup. -If policy routing is used, it may be a different route. - -\end{itemize} - -Note that this operation is not equivalent to \verb|ip route show|. -\verb|show| shows existing routes. \verb|get| resolves them and -creates new clones if necessary. Essentially, \verb|get| -is equivalent to sending a packet along this path. -If the \verb|iif| argument is not given, the kernel creates a route -to output packets towards the requested destination. -This is equivalent to pinging the destination -with a subsequent {\tt ip route ls cache}, however, no packets are -actually sent. With the \verb|iif| argument, the kernel pretends -that a packet arrived from this interface and searches for -a path to forward the packet. - -\paragraph{Output format:} This command outputs routes in the same -format as \verb|ip route ls|. - -\paragraph{Examples:} -\begin{itemize} -\item Find a route to output packets to 193.233.7.82: -\begin{verbatim} -kuznet@amber:~ $ ip route get 193.233.7.82 -193.233.7.82 dev eth0 src 193.233.7.65 realms inr.ac - cache mtu 1500 rtt 300 -kuznet@amber:~ $ -\end{verbatim} - -\item Find a route to forward packets arriving on \verb|eth0| -from 193.233.7.82 and destined for 193.233.7.82: -\begin{verbatim} -kuznet@amber:~ $ ip r g 193.233.7.82 from 193.233.7.82 iif eth0 -193.233.7.82 from 193.233.7.82 dev eth0 src 193.233.7.65 \ - realms inr.ac/inr.ac - cache <src-direct,redirect> mtu 1500 rtt 300 iif eth0 -kuznet@amber:~ $ -\end{verbatim} -\begin{NB} - \label{NB-nature-of-strangeness} - This is the command that created the funny route from 193.233.7.82 - looped back to 193.233.7.82 (cf.\ NB on~p.\pageref{NB-strange-route}). - Note the \verb|redirect| flag on it. -\end{NB} - -\item Find a multicast route for packets arriving on \verb|eth0| -from host 193.233.7.82 and destined for multicast group 224.2.127.254 -(it is assumed that a multicast routing daemon is running. -In this case, it is \verb|pimd|) -\begin{verbatim} -kuznet@amber:~ $ ip r g 224.2.127.254 from 193.233.7.82 iif eth0 -multicast 224.2.127.254 from 193.233.7.82 dev lo \ - src 193.233.7.65 realms inr.ac/cosmos - cache <mc> iif eth0 Oifs: eth1 pimreg -kuznet@amber:~ $ -\end{verbatim} -This route differs from the ones seen before. It contains a ``normal'' part -and a ``multicast'' part. The normal part is used to deliver (or not to -deliver) the packet to local IP listeners. In this case the router -is not a member -of this group, so that route has no \verb|local| flag and only -forwards packets. The output device for such entries is always loopback. -The multicast part consists of an additional \verb|Oifs:| list showing -the output interfaces. -\end{itemize} - - -It is time for a more complicated example. Let us add an invalid -gatewayed route for a destination which is really directly connected: -\begin{verbatim} -netadm@alisa:~ # ip route add 193.233.7.98 via 193.233.7.254 -netadm@alisa:~ # ip route get 193.233.7.98 -193.233.7.98 via 193.233.7.254 dev eth0 src 193.233.7.90 - cache mtu 1500 rtt 3072 -netadm@alisa:~ # -\end{verbatim} -and probe it with ping: -\begin{verbatim} -netadm@alisa:~ # ping -n 193.233.7.98 -PING 193.233.7.98 (193.233.7.98) from 193.233.7.90 : 56 data bytes -From 193.233.7.254: Redirect Host(New nexthop: 193.233.7.98) -64 bytes from 193.233.7.98: icmp_seq=0 ttl=255 time=3.5 ms -From 193.233.7.254: Redirect Host(New nexthop: 193.233.7.98) -64 bytes from 193.233.7.98: icmp_seq=1 ttl=255 time=2.2 ms -64 bytes from 193.233.7.98: icmp_seq=2 ttl=255 time=0.4 ms -64 bytes from 193.233.7.98: icmp_seq=3 ttl=255 time=0.4 ms -64 bytes from 193.233.7.98: icmp_seq=4 ttl=255 time=0.4 ms -^C ---- 193.233.7.98 ping statistics --- -5 packets transmitted, 5 packets received, 0% packet loss -round-trip min/avg/max = 0.4/1.3/3.5 ms -netadm@alisa:~ # -\end{verbatim} -What happened? Router 193.233.7.254 understood that we have a much -better path to the destination and sent us an ICMP redirect message. -We may retry \verb|ip route get| to see what we have in the routing -tables now: -\begin{verbatim} -netadm@alisa:~ # ip route get 193.233.7.98 -193.233.7.98 dev eth0 src 193.233.7.90 - cache <redirected> mtu 1500 rtt 3072 -netadm@alisa:~ # -\end{verbatim} - - - -\section{{\tt ip rule} --- routing policy database management} -\label{IP-RULE} - -\paragraph{Abbreviations:} \verb|rule|, \verb|ru|. - -\paragraph{Object:} \verb|rule|s in the routing policy database control -the route selection algorithm. - -Classic routing algorithms used in the Internet make routing decisions -based only on the destination address of packets (and in theory, -but not in practice, on the TOS field). The seminal review of classic -routing algorithms and their modifications can be found in~\cite{RFC1812}. - -In some circumstances we want to route packets differently depending not only -on destination addresses, but also on other packet fields: source address, -IP protocol, transport protocol ports or even packet payload. -This task is called ``policy routing''. - -\begin{NB} - ``policy routing'' $\neq$ ``routing policy''. - -\noindent ``policy routing'' $=$ ``cunning routing''. - -\noindent ``routing policy'' $=$ ``routing tactics'' or ``routing plan''. -\end{NB} - -To solve this task, the conventional destination based routing table, ordered -according to the longest match rule, is replaced with a ``routing policy -database'' (or RPDB), which selects routes -by executing some set of rules. The rules may have lots of keys of different -natures and therefore they have no natural ordering, but one imposed -by the administrator. Linux-2.2 RPDB is a linear list of rules -ordered by numeric priority value. -RPDB explicitly allows matching a few packet fields: - -\begin{itemize} -\item packet source address. -\item packet destination address. -\item TOS. -\item incoming interface (which is packet metadata, rather than a packet field). -\end{itemize} - -Matching IP protocols and transport ports is also possible, -indirectly, via \verb|ipchains|, by exploiting their ability -to mark some classes of packets with \verb|fwmark|. Therefore, -\verb|fwmark| is also included in the set of keys checked by rules. - -Each policy routing rule consists of a {\em selector\/} and an {\em action\/} -predicate. The RPDB is scanned in the order of increasing priority. The selector -of each rule is applied to \{source address, destination address, incoming -interface, tos, fwmark\} and, if the selector matches the packet, -the action is performed. The action predicate may return with success. -In this case, it will either give a route or failure indication -and the RPDB lookup is terminated. Otherwise, the RPDB program -continues on the next rule. - -What is the action, semantically? The natural action is to select the -nexthop and the output device. This is what -Cisco IOS~\cite{IOS} does. Let us call it ``match \& set''. -The Linux-2.2 approach is more flexible. The action includes -lookups in destination-based routing tables and selecting -a route from these tables according to the classic longest match algorithm. -The ``match \& set'' approach is the simplest case of the Linux one. It is realized -when a second level routing table contains a single default route. -Recall that Linux-2.2 supports multiple tables -managed with the \verb|ip route| command, described in the previous section. - -At startup time the kernel configures the default RPDB consisting of three -rules: - -\begin{enumerate} -\item Priority: 0, Selector: match anything, Action: lookup routing -table \verb|local| (ID 255). -The \verb|local| table is a special routing table containing -high priority control routes for local and broadcast addresses. - -Rule 0 is special. It cannot be deleted or overridden. - - -\item Priority: 32766, Selector: match anything, Action: lookup routing -table \verb|main| (ID 254). -The \verb|main| table is the normal routing table containing all non-policy -routes. This rule may be deleted and/or overridden with other -ones by the administrator. - -\item Priority: 32767, Selector: match anything, Action: lookup routing -table \verb|default| (ID 253). -The \verb|default| table is empty. It is reserved for some -post-processing if no previous default rules selected the packet. -This rule may also be deleted. - -\end{enumerate} - -Do not confuse routing tables with rules: rules point to routing tables, -several rules may refer to one routing table and some routing tables -may have no rules pointing to them. If the administrator deletes all the rules -referring to a table, the table is not used, but it still exists -and will disappear only after all the routes contained in it are deleted. - - -\paragraph{Rule attributes:} Each RPDB entry has additional -attributes. F.e.\ each rule has a pointer to some routing -table. NAT and masquerading rules have an attribute to select new IP -address to translate/masquerade. Besides that, rules have some -optional attributes, which routes have, namely \verb|realms|. -These values do not override those contained in the routing tables. They -are only used if the route did not select any attributes. - - -\paragraph{Rule types:} The RPDB may contain rules of the following -types: -\begin{itemize} -\item \verb|unicast| --- the rule prescribes to return the route found -in the routing table referenced by the rule. -\item \verb|blackhole| --- the rule prescribes to silently drop the packet. -\item \verb|unreachable| --- the rule prescribes to generate a ``Network -is unreachable'' error. -\item \verb|prohibit| --- the rule prescribes to generate -``Communication is administratively prohibited'' error. -\item \verb|nat| --- the rule prescribes to translate the source address -of the IP packet into some other value. More about NAT is -in Appendix~\ref{ROUTE-NAT}, p.\pageref{ROUTE-NAT}. -\end{itemize} - - -\paragraph{Commands:} \verb|add|, \verb|delete| and \verb|show| -(or \verb|list|). - -\subsection{{\tt ip rule add} --- insert a new rule\\ - {\tt ip rule delete} --- delete a rule} -\label{IP-RULE-ADD} - -\paragraph{Abbreviations:} \verb|add|, \verb|a|; \verb|delete|, \verb|del|, - \verb|d|. - -\paragraph{Arguments:} - -\begin{itemize} -\item \verb|type TYPE| (default) - ---- the type of this rule. The list of valid types was given in the previous -subsection. - -\item \verb|from PREFIX| - ---- select the source prefix to match. - -\item \verb|to PREFIX| - ---- select the destination prefix to match. - -\item \verb|iif NAME| - ---- select the incoming device to match. If the interface is loopback, -the rule only matches packets originating from this host. This means that you -may create separate routing tables for forwarded and local packets and, -hence, completely segregate them. - -\item \verb|tos TOS| or \verb|dsfield TOS| - ---- select the TOS value to match. - -\item \verb|fwmark MARK| - ---- select the \verb|fwmark| value to match. - -\item \verb|priority PREFERENCE| - ---- the priority of this rule. Each rule should have an explicitly -set {\em unique\/} priority value. -\begin{NB} - Really, for historical reasons \verb|ip rule add| does not require a - priority value and allows them to be non-unique. - If the user does not supplied a priority, it is selected by the kernel. - If the user creates a rule with a priority value that - already exists, the kernel does not reject the request. It adds - the new rule before all old rules of the same priority. - - It is mistake in design, no more. And it will be fixed one day, - so do not rely on this feature. Use explicit priorities. -\end{NB} - - -\item \verb|table TABLEID| - ---- the routing table identifier to lookup if the rule selector matches. - -\item \verb|realms FROM/TO| - ---- Realms to select if the rule matched and the routing table lookup -succeeded. Realm \verb|TO| is only used if the route did not select -any realm. - -\item \verb|nat ADDRESS| - ---- The base of the IP address block to translate (for source addresses). -The \verb|ADDRESS| may be either the start of the block of NAT addresses -(selected by NAT routes) or in linux-2.2 a local host address (or even zero). -In the last case the router does not translate the packets, -but masquerades them to this address; this feature disappered in 2.4. -More about NAT is in Appendix~\ref{ROUTE-NAT}, -p.\pageref{ROUTE-NAT}. - -\end{itemize} - -\paragraph{Warning:} Changes to the RPDB made with these commands -do not become active immediately. It is assumed that after -a script finishes a batch of updates, it flushes the routing cache -with \verb|ip route flush cache|. - -\paragraph{Examples:} -\begin{itemize} -\item Route packets with source addresses from 192.203.80/24 -according to routing table \verb|inr.ruhep|: -\begin{verbatim} -ip ru add from 192.203.80.0/24 table inr.ruhep prio 220 -\end{verbatim} - -\item Translate packet source address 193.233.7.83 into 192.203.80.144 -and route it according to table \#1 (actually, it is \verb|inr.ruhep|): -\begin{verbatim} -ip ru add from 193.233.7.83 nat 192.203.80.144 table 1 prio 320 -\end{verbatim} - -\item Delete the unused default rule: -\begin{verbatim} -ip ru del prio 32767 -\end{verbatim} - -\end{itemize} - - - -\subsection{{\tt ip rule show} --- list rules} -\label{IP-RULE-SHOW} - -\paragraph{Abbreviations:} \verb|show|, \verb|list|, \verb|sh|, \verb|ls|, \verb|l|. - - -\paragraph{Arguments:} Good news, this is one command that has no arguments. - -\paragraph{Output format:} - -\begin{verbatim} -kuznet@amber:~ $ ip ru ls -0: from all lookup local -200: from 192.203.80.0/24 to 193.233.7.0/24 lookup main -210: from 192.203.80.0/24 to 192.203.80.0/24 lookup main -220: from 192.203.80.0/24 lookup inr.ruhep realms inr.ruhep/radio-msu -300: from 193.233.7.83 to 193.233.7.0/24 lookup main -310: from 193.233.7.83 to 192.203.80.0/24 lookup main -320: from 193.233.7.83 lookup inr.ruhep map-to 192.203.80.144 -32766: from all lookup main -kuznet@amber:~ $ -\end{verbatim} - -In the first column is the rule priority value followed -by a colon. Then the selectors follow. Each key is prefixed -with the same keyword that was used to create the rule. - -The keyword \verb|lookup| is followed by a routing table identifier, -as it is recorded in the file \verb|/etc/iproute2/rt_tables|. - -If the rule does NAT (f.e.\ rule \#320), it is shown by the keyword -\verb|map-to| followed by the start of the block of addresses to map. - -The sense of this example is pretty simple. The prefixes -192.203.80.0/24 and 193.233.7.0/24 form the internal network, but -they are routed differently when the packets leave it. -Besides that, the host 193.233.7.83 is translated into -another prefix to look like 192.203.80.144 when talking -to the outer world. - - - -\section{{\tt ip maddress} --- multicast addresses management} -\label{IP-MADDR} - -\paragraph{Object:} \verb|maddress| objects are multicast addresses. - -\paragraph{Commands:} \verb|add|, \verb|delete|, \verb|show| (or \verb|list|). - -\subsection{{\tt ip maddress show} --- list multicast addresses} - -\paragraph{Abbreviations:} \verb|show|, \verb|list|, \verb|sh|, \verb|ls|, \verb|l|. - -\paragraph{Arguments:} - -\begin{itemize} - -\item \verb|dev NAME| (default) - ---- the device name. - -\end{itemize} - -\paragraph{Output format:} - -\begin{verbatim} -kuznet@alisa:~ $ ip maddr ls dummy -2: dummy - link 33:33:00:00:00:01 - link 01:00:5e:00:00:01 - inet 224.0.0.1 users 2 - inet6 ff02::1 -kuznet@alisa:~ $ -\end{verbatim} - -The first line of the output shows the interface index and its name. -Then the multicast address list follows. Each line starts with the -protocol identifier. The word \verb|link| denotes a link layer -multicast addresses. - -If a multicast address has more than one user, the number -of users is shown after the \verb|users| keyword. - -One additional feature not present in the example above -is the \verb|static| flag, which indicates that the address was joined -with \verb|ip maddr add|. See the following subsection. - - - -\subsection{{\tt ip maddress add} --- add a multicast address\\ - {\tt ip maddress delete} --- delete a multicast address} - -\paragraph{Abbreviations:} \verb|add|, \verb|a|; \verb|delete|, \verb|del|, \verb|d|. - -\paragraph{Description:} these commands attach/detach -a static link layer multicast address to listen on the interface. -Note that it is impossible to join protocol multicast groups -statically. This command only manages link layer addresses. - - -\paragraph{Arguments:} - -\begin{itemize} -\item \verb|address LLADDRESS| (default) - ---- the link layer multicast address. - -\item \verb|dev NAME| - ---- the device to join/leave this multicast address. - -\end{itemize} - - -\paragraph{Example:} Let us continue with the example from the previous subsection. - -\begin{verbatim} -netadm@alisa:~ # ip maddr add 33:33:00:00:00:01 dev dummy -netadm@alisa:~ # ip -0 maddr ls dummy -2: dummy - link 33:33:00:00:00:01 users 2 static - link 01:00:5e:00:00:01 -netadm@alisa:~ # ip maddr del 33:33:00:00:00:01 dev dummy -\end{verbatim} - -\begin{NB} - Neither \verb|ip| nor the kernel check for multicast address validity. - Particularly, this means that you can try to load a unicast address - instead of a multicast address. Most drivers will ignore such addresses, - but several (f.e.\ Tulip) will intern it to their on-board filter. - The effects may be strange. Namely, the addresses become additional - local link addresses and, if you loaded the address of another host - to the router, wait for duplicated packets on the wire. - It is not a bug, but rather a hole in the API and intra-kernel interfaces. - This feature is really more useful for traffic monitoring, but using it - with Linux-2.2 you {\em have to\/} be sure that the host is not - a router and, especially, that it is not a transparent proxy or masquerading - agent. -\end{NB} - - - -\section{{\tt ip mroute} --- multicast routing cache management} -\label{IP-MROUTE} - -\paragraph{Abbreviations:} \verb|mroute|, \verb|mr|. - -\paragraph{Object:} \verb|mroute| objects are multicast routing cache -entries created by a user level mrouting daemon -(f.e.\ \verb|pimd| or \verb|mrouted|). - -Due to the limitations of the current interface to the multicast routing -engine, it is impossible to change \verb|mroute| objects administratively, -so we may only display them. This limitation will be removed -in the future. - -\paragraph{Commands:} \verb|show| (or \verb|list|). - - -\subsection{{\tt ip mroute show} --- list mroute cache entries} - -\paragraph{Abbreviations:} \verb|show|, \verb|list|, \verb|sh|, \verb|ls|, \verb|l|. - -\paragraph{Arguments:} - -\begin{itemize} -\item \verb|to PREFIX| (default) - ---- the prefix selecting the destination multicast addresses to list. - - -\item \verb|iif NAME| - ---- the interface on which multicast packets are received. - - -\item \verb|from PREFIX| - ---- the prefix selecting the IP source addresses of the multicast route. - - -\end{itemize} - -\paragraph{Output format:} - -\begin{verbatim} -kuznet@amber:~ $ ip mroute ls -(193.232.127.6, 224.0.1.39) Iif: unresolved -(193.232.244.34, 224.0.1.40) Iif: unresolved -(193.233.7.65, 224.66.66.66) Iif: eth0 Oifs: pimreg -kuznet@amber:~ $ -\end{verbatim} - -Each line shows one (S,G) entry in the multicast routing cache, -where S is the source address and G is the multicast group. \verb|Iif| is -the interface on which multicast packets are expected to arrive. -If the word \verb|unresolved| is there instead of the interface name, -it means that the routing daemon still hasn't resolved this entry. -The keyword \verb|oifs| is followed by a list of output interfaces, separated -by spaces. If a multicast routing entry is created with non-trivial -TTL scope, administrative distances are appended to the device names -in the \verb|oifs| list. - -\paragraph{Statistics:} The \verb|-statistics| option also prints the -number of packets and bytes forwarded along this route and -the number of packets that arrived on the wrong interface, if this number is not zero. - -\begin{verbatim} -kuznet@amber:~ $ ip -s mr ls 224.66/16 -(193.233.7.65, 224.66.66.66) Iif: eth0 Oifs: pimreg - 9383 packets, 300256 bytes -kuznet@amber:~ $ -\end{verbatim} - - -\section{{\tt ip tunnel} --- tunnel configuration} -\label{IP-TUNNEL} - -\paragraph{Abbreviations:} \verb|tunnel|, \verb|tunl|. - -\paragraph{Object:} \verb|tunnel| objects are tunnels, encapsulating -packets in IPv4 packets and then sending them over the IP infrastructure. - -\paragraph{Commands:} \verb|add|, \verb|delete|, \verb|change|, \verb|show| -(or \verb|list|). - -\paragraph{See also:} A more informal discussion of tunneling -over IP and the \verb|ip tunnel| command can be found in~\cite{IP-TUNNELS}. - -\subsection{{\tt ip tunnel add} --- add a new tunnel\\ - {\tt ip tunnel change} --- change an existing tunnel\\ - {\tt ip tunnel delete} --- destroy a tunnel} - -\paragraph{Abbreviations:} \verb|add|, \verb|a|; \verb|change|, \verb|chg|; -\verb|delete|, \verb|del|, \verb|d|. - - -\paragraph{Arguments:} - -\begin{itemize} - -\item \verb|name NAME| (default) - ---- select the tunnel device name. - -\item \verb|mode MODE| - ---- set the tunnel mode. Three modes are currently available: - \verb|ipip|, \verb|sit| and \verb|gre|. - -\item \verb|remote ADDRESS| - ---- set the remote endpoint of the tunnel. - -\item \verb|local ADDRESS| - ---- set the fixed local address for tunneled packets. -It must be an address on another interface of this host. - -\item \verb|ttl N| - ---- set a fixed TTL \verb|N| on tunneled packets. - \verb|N| is a number in the range 1--255. 0 is a special value - meaning that packets inherit the TTL value. - The default value is: \verb|inherit|. - -\item \verb|tos T| or \verb|dsfield T| - ---- set a fixed TOS \verb|T| on tunneled packets. - The default value is: \verb|inherit|. - - - -\item \verb|dev NAME| - ---- bind the tunnel to the device \verb|NAME| so that - tunneled packets will only be routed via this device and will - not be able to escape to another device when the route to endpoint changes. - -\item \verb|nopmtudisc| - ---- disable Path MTU Discovery on this tunnel. - It is enabled by default. Note that a fixed ttl is incompatible - with this option: tunnelling with a fixed ttl always makes pmtu discovery. - -\item \verb|key K|, \verb|ikey K|, \verb|okey K| - ---- (only GRE tunnels) use keyed GRE with key \verb|K|. \verb|K| is - either a number or an IP address-like dotted quad. - The \verb|key| parameter sets the key to use in both directions. - The \verb|ikey| and \verb|okey| parameters set different keys for input and output. - - -\item \verb|csum|, \verb|icsum|, \verb|ocsum| - ---- (only GRE tunnels) generate/require checksums for tunneled packets. - The \verb|ocsum| flag calculates checksums for outgoing packets. - The \verb|icsum| flag requires that all input packets have the correct - checksum. The \verb|csum| flag is equivalent to the combination - ``\verb|icsum| \verb|ocsum|''. - -\item \verb|seq|, \verb|iseq|, \verb|oseq| - ---- (only GRE tunnels) serialize packets. - The \verb|oseq| flag enables sequencing of outgoing packets. - The \verb|iseq| flag requires that all input packets are serialized. - The \verb|seq| flag is equivalent to the combination ``\verb|iseq| \verb|oseq|''. - -\begin{NB} - I think this option does not - work. At least, I did not test it, did not debug it and - do not even understand how it is supposed to work or for what - purpose Cisco planned to use it. Do not use it. -\end{NB} - - -\end{itemize} - -\paragraph{Example:} Create a pointopoint IPv6 tunnel with maximal TTL of 32. -\begin{verbatim} -netadm@amber:~ # ip tunl add Cisco mode sit remote 192.31.7.104 \ - local 192.203.80.142 ttl 32 -\end{verbatim} - -\subsection{{\tt ip tunnel show} --- list tunnels} - -\paragraph{Abbreviations:} \verb|show|, \verb|list|, \verb|sh|, \verb|ls|, \verb|l|. - - -\paragraph{Arguments:} None. - -\paragraph{Output format:} -\begin{verbatim} -kuznet@amber:~ $ ip tunl ls Cisco -Cisco: ipv6/ip remote 192.31.7.104 local 192.203.80.142 ttl 32 -kuznet@amber:~ $ -\end{verbatim} -The line starts with the tunnel device name followed by a colon. -Then the tunnel mode follows. The parameters of the tunnel are listed -with the same keywords that were used when creating the tunnel. - -\paragraph{Statistics:} - -\begin{verbatim} -kuznet@amber:~ $ ip -s tunl ls Cisco -Cisco: ipv6/ip remote 192.31.7.104 local 192.203.80.142 ttl 32 -RX: Packets Bytes Errors CsumErrs OutOfSeq Mcasts - 12566 1707516 0 0 0 0 -TX: Packets Bytes Errors DeadLoop NoRoute NoBufs - 13445 1879677 0 0 0 0 -kuznet@amber:~ $ -\end{verbatim} -Essentially, these numbers are the same as the numbers -printed with {\tt ip -s link show} -(sec.\ref{IP-LINK-SHOW}, p.\pageref{IP-LINK-SHOW}) but the tags are different -to reflect that they are tunnel specific. -\begin{itemize} -\item \verb|CsumErrs| --- the total number of packets dropped -because of checksum failures for a GRE tunnel with checksumming enabled. -\item \verb|OutOfSeq| --- the total number of packets dropped -because they arrived out of sequence for a GRE tunnel with -serialization enabled. -\item \verb|Mcasts| --- the total number of multicast packets -received on a broadcast GRE tunnel. -\item \verb|DeadLoop| --- the total number of packets which were not -transmitted because the tunnel is looped back to itself. -\item \verb|NoRoute| --- the total number of packets which were not -transmitted because there is no IP route to the remote endpoint. -\item \verb|NoBufs| --- the total number of packets which were not -transmitted because the kernel failed to allocate a buffer. -\end{itemize} - - -\section{{\tt ip monitor} and {\tt rtmon} --- state monitoring} -\label{IP-MONITOR} - -The \verb|ip| utility can monitor the state of devices, addresses -and routes continuously. This option has a slightly different format. -Namely, -the \verb|monitor| command is the first in the command line and then -the object list follows: -\begin{verbatim} - ip monitor [ file FILE ] [ all | OBJECT-LIST ] -\end{verbatim} -\verb|OBJECT-LIST| is the list of object types that we want to monitor. -It may contain \verb|link|, \verb|address| and \verb|route|. -If no \verb|file| argument is given, \verb|ip| opens RTNETLINK, -listens on it and dumps state changes in the format described -in previous sections. - -If a file name is given, it does not listen on RTNETLINK, -but opens the file containing RTNETLINK messages saved in binary format -and dumps them. Such a history file can be generated with the -\verb|rtmon| utility. This utility has a command line syntax similar to -\verb|ip monitor|. -Ideally, \verb|rtmon| should be started before -the first network configuration command is issued. F.e.\ if -you insert: -\begin{verbatim} - rtmon file /var/log/rtmon.log -\end{verbatim} -in a startup script, you will be able to view the full history -later. - -Certainly, it is possible to start \verb|rtmon| at any time. -It prepends the history with the state snapshot dumped at the moment -of starting. - - -\section{Route realms and policy propagation, {\tt rtacct}} -\label{RT-REALMS} - -On routers using OSPF ASE or, especially, the BGP protocol, routing -tables may be huge. If we want to classify or to account for the packets -per route, we will have to keep lots of information. Even worse, if we -want to distinguish the packets not only by their destination, but -also by their source, the task gets quadratic complexity and its solution -is physically impossible. - -One approach to propagating the policy from routing protocols -to the forwarding engine has been proposed in~\cite{IOS-BGP-PP}. -Essentially, Cisco Policy Propagation via BGP is based on the fact -that dedicated routers all have the RIB (Routing Information Base) -close to the forwarding engine, so policy routing rules can -check all the route attributes, including ASPATH information -and community strings. - -The Linux architecture, splitting the RIB (maintained by a user level -daemon) and the kernel based FIB (Forwarding Information Base), -does not allow such a simple approach. - -It is to our fortune because there is another solution -which allows even more flexible policy and richer semantics. - -Namely, routes can be clustered together in user space, based on their -attributes. F.e.\ a BGP router knows route ASPATH, its community; -an OSPF router knows the route tag or its area. The administrator, when adding -routes manually, also knows their nature. Providing that the number of such -aggregates (we call them {\em realms\/}) is low, the task of full -classification both by source and destination becomes quite manageable. - -So each route may be assigned to a realm. It is assumed that -this identification is made by a routing daemon, but static routes -can also be handled manually with \verb|ip route| (see sec.\ref{IP-ROUTE}, -p.\pageref{IP-ROUTE}). -\begin{NB} - There is a patch to \verb|gated|, allowing classification of routes - to realms with all the set of policy rules implemented in \verb|gated|: - by prefix, by ASPATH, by origin, by tag etc. -\end{NB} - -To facilitate the construction (f.e.\ in case the routing -daemon is not aware of realms), missing realms may be completed -with routing policy rules, see sec.~\ref{IP-RULE}, p.\pageref{IP-RULE}. - -For each packet the kernel calculates a tuple of realms: source realm -and destination realm, using the following algorithm: - -\begin{enumerate} -\item If the route has a realm, the destination realm of the packet is set to it. -\item If the rule has a source realm, the source realm of the packet is set to it. -If the destination realm was not inherited from the route and the rule has a destination realm, -it is also set. -\item If at least one of the realms is still unknown, the kernel finds -the reversed route to the source of the packet. -\item If the source realm is still unknown, get it from the reversed route. -\item If one of the realms is still unknown, swap the realms of reversed -routes and apply step 2 again. -\end{enumerate} - -After this procedure is completed we know what realm the packet -arrived from and the realm where it is going to propagate to. -If some of the realms are unknown, they are initialized to zero -(or realm \verb|unknown|). - -The main application of realms is the TC \verb|route| classifier~\cite{TC-CREF}, -where they are used to help assign packets to traffic classes, -to account, police and schedule them according to this -classification. - -A much simpler but still very useful application is incoming packet -accounting by realms. The kernel gathers a packet statistics summary -which can be viewed with the \verb|rtacct| utility. -\begin{verbatim} -kuznet@amber:~ $ rtacct russia -Realm BytesTo PktsTo BytesFrom PktsFrom -russia 20576778 169176 47080168 153805 -kuznet@amber:~ $ -\end{verbatim} -This shows that this router received 153805 packets from -the realm \verb|russia| and forwarded 169176 packets to \verb|russia|. -The realm \verb|russia| consists of routes with ASPATHs not leaving -Russia. - -Note that locally originating packets are not accounted here, -\verb|rtacct| shows incoming packets only. Using the \verb|route| -classifier (see~\cite{TC-CREF}) you can get even more detailed -accounting information about outgoing packets, optionally -summarizing traffic not only by source or destination, but -by any pair of source and destination realms. - - -\begin{thebibliography}{99} -\addcontentsline{toc}{section}{References} -\bibitem{RFC-NDISC} T.~Narten, E.~Nordmark, W.~Simpson. -``Neighbor Discovery for IP Version 6 (IPv6)'', RFC-2461. - -\bibitem{RFC-ADDRCONF} S.~Thomson, T.~Narten. -``IPv6 Stateless Address Autoconfiguration'', RFC-2462. - -\bibitem{RFC1812} F.~Baker. -``Requirements for IP Version 4 Routers'', RFC-1812. - -\bibitem{RFC1122} R.~T.~Braden. -``Requirements for Internet hosts --- communication layers'', RFC-1122. - -\bibitem{IOS} ``Cisco IOS Release 12.0 Network Protocols -Command Reference, Part 1'' and -``Cisco IOS Release 12.0 Quality of Service Solutions -Configuration Guide: Configuring Policy-Based Routing'',\\ -http://www.cisco.com/univercd/cc/td/doc/product/software/ios120. - -\bibitem{IP-TUNNELS} A.~N.~Kuznetsov. -``Tunnels over IP in Linux-2.2'', \\ -In: {\tt ftp://ftp.inr.ac.ru/ip-routing/iproute2-current.tar.gz}. - -\bibitem{TC-CREF} A.~N.~Kuznetsov. ``TC Command Reference'',\\ -In: {\tt ftp://ftp.inr.ac.ru/ip-routing/iproute2-current.tar.gz}. - -\bibitem{IOS-BGP-PP} ``Cisco IOS Release 12.0 Quality of Service Solutions -Configuration Guide: Configuring QoS Policy Propagation via -Border Gateway Protocol'',\\ -http://www.cisco.com/univercd/cc/td/doc/product/software/ios120. - -\bibitem{RFC-DHCP} R.~Droms. -``Dynamic Host Configuration Protocol.'', RFC-2131 - -\end{thebibliography} - - - - -\appendix -\addcontentsline{toc}{section}{Appendix} - -\section{Source address selection} -\label{ADDR-SEL} - -When a host creates an IP packet, it must select some source -address. Correct source address selection is a critical procedure, -because it gives the receiver the information needed to deliver a -reply. If the source is selected incorrectly, in the best case, -the backward path may appear different to the forward one which -is harmful for performance. In the worst case, when the addresses -are administratively scoped, the reply may be lost entirely. - -Linux-2.2 selects source addresses using the following algorithm: - -\begin{itemize} -\item -The application may select a source address explicitly with \verb|bind(2)| -syscall or supplying it to \verb|sendmsg(2)| via the ancillary data object -\verb|IP_PKTINFO|. In this case the kernel only checks the validity -of the address and never tries to ``improve'' an incorrect user choice, -generating an error instead. -\begin{NB} - Never say ``Never''. The sysctl option \verb|ip_dynaddr| breaks - this axiom. It has been made deliberately with the purpose - of automatically reselecting the address on hosts with dynamic dial-out interfaces. - However, this hack {\em must not\/} be used on multihomed hosts - and especially on routers: it would break them. -\end{NB} - - -\item Otherwise, IP routing tables can contain an explicit source -address hint for this destination. The hint is set with the \verb|src| parameter -to the \verb|ip route| command, sec.\ref{IP-ROUTE}, p.\pageref{IP-ROUTE}. - - -\item Otherwise, the kernel searches through the list of addresses -attached to the interface through which the packets will be routed. -The search strategies are different for IP and IPv6. Namely: - -\begin{itemize} -\item IPv6 searches for the first valid, not deprecated address -with the same scope as the destination. - -\item IP searches for the first valid address with a scope wider -than the scope of the destination but it prefers addresses -which fall to the same subnet as the nexthop of the route -to the destination. Unlike IPv6, the scopes of IPv4 destinations -are not encoded in their addresses but are supplied -in routing tables instead (the \verb|scope| parameter to the \verb|ip route| command, -sec.\ref{IP-ROUTE}, p.\pageref{IP-ROUTE}). - -\end{itemize} - - -\item Otherwise, if the scope of the destination is \verb|link| or \verb|host|, -the algorithm fails and returns a zero source address. - -\item Otherwise, all interfaces are scanned to search for an address -with an appropriate scope. The loopback device \verb|lo| is always the first -in the search list, so that if an address with global scope (not 127.0.0.1!) -is configured on loopback, it is always preferred. - -\end{itemize} - - -\section{Proxy ARP/NDISC} -\label{PROXY-NEIGH} - -Routers may answer ARP/NDISC solicitations on behalf of other hosts. -In Linux-2.2 proxy ARP on an interface may be enabled -by setting the kernel \verb|sysctl| variable -\verb|/proc/sys/net/ipv4/conf/<dev>/proxy_arp| to 1. After this, the router -starts to answer ARP requests on the interface \verb|<dev>|, provided -the route to the requested destination does {\em not\/} go back via the same -device. - -The variable \verb|/proc/sys/net/ipv4/conf/all/proxy_arp| enables proxy -ARP on all the IP devices. - -However, this approach fails in the case of IPv6 because the router -must join the solicited node multicast address to listen for the corresponding -NDISC queries. It means that proxy NDISC is possible only on a per destination -basis. - -Logically, proxy ARP/NDISC is not a kernel task. It can easily be implemented -in user space. However, similar functionality was present in BSD kernels -and in Linux-2.0, so we have to preserve it at least to the extent that -is standardized in BSD. -\begin{NB} - Linux-2.0 ARP had a feature called {\em subnet\/} proxy ARP. - It is replaced with the sysctl flag in Linux-2.2. -\end{NB} - - -The \verb|ip| utility provides a way to manage proxy ARP/NDISC -with the \verb|ip neigh| command, namely: -\begin{verbatim} - ip neigh add proxy ADDRESS [ dev NAME ] -\end{verbatim} -adds a new proxy ARP/NDISC record and -\begin{verbatim} - ip neigh del proxy ADDRESS [ dev NAME ] -\end{verbatim} -deletes it. - -If the name of the device is not given, the router will answer solicitations -for address \verb|ADDRESS| on all devices, otherwise it will only serve -the device \verb|NAME|. Even if the proxy entry is created with -\verb|ip neigh|, the router {\em will not\/} answer a query if the route -to the destination goes back via the interface from which the solicitation -was received. - -It is important to emphasize that proxy entries have {\em no\/} -parameters other than these (IP/IPv6 address and optional device). -Particularly, the entry does not store any link layer address. -It always advertises the station address of the interface -on which it sends advertisements (i.e. it's own station address). - -\section{Route NAT status} -\label{ROUTE-NAT} - -NAT (or ``Network Address Translation'') remaps some parts -of the IP address space into other ones. Linux-2.2 route NAT is supposed -to be used to facilitate policy routing by rewriting addresses -to other routing domains or to help while renumbering sites -to another prefix. - -\paragraph{What it is not:} -It is necessary to emphasize that {\em it is not supposed\/} -to be used to compress address space or to split load. -This is not missing functionality but a design principle. -Route NAT is {\em stateless\/}. It does not hold any state -about translated sessions. This means that it handles any number -of sessions flawlessly. But it also means that it is {\em static\/}. -It cannot detect the moment when the last TCP client stops -using an address. For the same reason, it will not help to split -load between several servers. -\begin{NB} -It is a pretty commonly held belief that it is useful to split load between -several servers with NAT. This is a mistake. All you get from this -is the requirement that the router keep the state of all the TCP connections -going via it. Well, if the router is so powerful, run apache on it. 8) -\end{NB} - -The second feature: it does not touch packet payload, -does not try to ``improve'' broken protocols by looking -through its data and mangling it. It mangles IP addresses, -only IP addresses and nothing but IP addresses. -This also, is not missing any functionality. - -To resume: if you need to compress address space or keep -active FTP clients happy, your choice is not route NAT but masquerading, -port forwarding, NAPT etc. -\begin{NB} -By the way, you may also want to look at -http://www.suse.com/\~mha/HyperNews/get/linux-ip-nat.html -\end{NB} - - -\paragraph{How it works.} -Some part of the address space is reserved for dummy addresses -which will look for all the world like some host addresses -inside your network. No other hosts may use these addresses, -however other routers may also be configured to translate them. -\begin{NB} -A great advantage of route NAT is that it may be used not -only in stub networks but in environments with arbitrarily complicated -structure. It does not firewall, it {\em forwards.} -\end{NB} -These addresses are selected by the \verb|ip route| command -(sec.\ref{IP-ROUTE-ADD}, p.\pageref{IP-ROUTE-ADD}). F.e.\ -\begin{verbatim} - ip route add nat 192.203.80.144 via 193.233.7.83 -\end{verbatim} -states that the single address 192.203.80.144 is a dummy NAT address. -For all the world it looks like a host address inside our network. -For neighbouring hosts and routers it looks like the local address -of the translating router. The router answers ARP for it, advertises -this address as routed via it, {\em et al\/}. When the router -receives a packet destined for 192.203.80.144, it replaces -this address with 193.233.7.83 which is the address of some real -host and forwards the packet. If you need to remap -blocks of addresses, you may use a command like: -\begin{verbatim} - ip route add nat 192.203.80.192/26 via 193.233.7.64 -\end{verbatim} -This command will map a block of 63 addresses 192.203.80.192-255 to -193.233.7.64-127. - -When an internal host (193.233.7.83 in the example above) -sends something to the outer world and these packets are forwarded -by our router, it should translate the source address 193.233.7.83 -into 192.203.80.144. This task is solved by setting a special -policy rule (sec.\ref{IP-RULE-ADD}, p.\pageref{IP-RULE-ADD}): -\begin{verbatim} - ip rule add prio 320 from 193.233.7.83 nat 192.203.80.144 -\end{verbatim} -This rule says that the source address 193.233.7.83 -should be translated into 192.203.80.144 before forwarding. -It is important that the address after the \verb|nat| keyword -is some NAT address, declared by {\tt ip route add nat}. -If it is just a random address the router will not map to it. -\begin{NB} -The exception is when the address is a local address of this -router (or 0.0.0.0) and masquerading is configured in the linux-2.2 -kernel. In this case the router will masquerade the packets as this address. -If 0.0.0.0 is selected, the result is equivalent to one -obtained with firewalling rules. Otherwise, you have the way -to order Linux to masquerade to this fixed address. -NAT mechanism used in linux-2.4 is more flexible than -masquerading, so that this feature has lost meaning and disabled. -\end{NB} - -If the network has non-trivial internal structure, it is -useful and even necessary to add rules disabling translation -when a packet does not leave this network. Let us return to the -example from sec.\ref{IP-RULE-SHOW} (p.\pageref{IP-RULE-SHOW}). -\begin{verbatim} -300: from 193.233.7.83 to 193.233.7.0/24 lookup main -310: from 193.233.7.83 to 192.203.80.0/24 lookup main -320: from 193.233.7.83 lookup inr.ruhep map-to 192.203.80.144 -\end{verbatim} -This block of rules causes normal forwarding when -packets from 193.233.7.83 do not leave networks 193.233.7/24 -and 192.203.80/24. Also, if the \verb|inr.ruhep| table does not -contain a route to the destination (which means that the routing -domain owning addresses from 192.203.80/24 is dead), no translation -will occur. Otherwise, the packets are translated. - -\paragraph{How to only translate selected ports:} -If you only want to translate selected ports (f.e.\ http) -and leave the rest intact, you may use \verb|ipchains| -to \verb|fwmark| a class of packets. -Suppose you did and all the packets from 193.233.7.83 -destined for port 80 are marked with marker 0x1234 in input fwchain. -In this case you may replace rule \#320 with: -\begin{verbatim} -320: from 193.233.7.83 fwmark 1234 lookup main map-to 192.203.80.144 -\end{verbatim} -and translation will only be enabled for outgoing http requests. - -\section{Example: minimal host setup} -\label{EXAMPLE-SETUP} - -The following script gives an example of a fault safe -setup of IP (and IPv6, if it is compiled into the kernel) -in the common case of a node attached to a single broadcast -network. A more advanced script, which may be used both on multihomed -hosts and on routers, is described in the following -section. - -The utilities used in the script may be found in the -directory ftp://ftp.inr.ac.ru/ip-routing/: -\begin{enumerate} -\item \verb|ip| --- package \verb|iproute2|. -\item \verb|arping| --- package \verb|iputils|. -\item \verb|rdisc| --- package \verb|iputils|. -\end{enumerate} -\begin{NB} -It also refers to a DHCP client, \verb|dhcpcd|. I should refrain from -recommending a good DHCP client to use. All that I can -say is that ISC \verb|dhcp-2.0b1pl6| patched with the patch that -can be found in the \verb|dhcp.bootp.rarp| subdirectory of -the same ftp site {\em does\/} work, -at least on Ethernet and Token Ring. -\end{NB} - -\begin{verbatim} -#! /bin/bash -\end{verbatim} -\begin{flushleft} -\# {\bf Usage: \verb|ifone ADDRESS[/PREFIX-LENGTH] [DEVICE]|}\\ -\# {\bf Parameters:}\\ -\# \$1 --- Static IP address, optionally followed by prefix length.\\ -\# \$2 --- Device name. If it is missing, \verb|eth0| is asssumed.\\ -\# F.e. \verb|ifone 193.233.7.90| -\end{flushleft} -\begin{verbatim} -dev=$2 -: ${dev:=eth0} -ipaddr= -\end{verbatim} -\# Parse IP address, splitting prefix length. -\begin{verbatim} -if [ "$1" != "" ]; then - ipaddr=${1%/*} - if [ "$1" != "$ipaddr" ]; then - pfxlen=${1#*/} - fi - : ${pfxlen:=24} -fi -pfx="${ipaddr}/${pfxlen}" -\end{verbatim} - -\begin{flushleft} -\# {\bf Step 0} --- enable loopback.\\ -\#\\ -\# This step is necessary on any networked box before attempt\\ -\# to configure any other device.\\ -\end{flushleft} -\begin{verbatim} -ip link set up dev lo -ip addr add 127.0.0.1/8 dev lo brd + scope host -\end{verbatim} -\begin{flushleft} -\# IPv6 autoconfigure themself on loopback.\\ -\#\\ -\# If user gave loopback as device, we add the address as alias and exit. -\end{flushleft} -\begin{verbatim} -if [ "$dev" = "lo" ]; then - if [ "$ipaddr" != "" -a "$ipaddr" != "127.0.0.1" ]; then - ip address add $ipaddr dev $dev - exit $? - fi - exit 0 -fi -\end{verbatim} - -\noindent\# {\bf Step 1} --- enable device \verb|$dev| - -\begin{verbatim} -if ! ip link set up dev $dev ; then - echo "Cannot enable interface $dev. Aborting." 1>&2 - exit 1 -fi -\end{verbatim} -\begin{flushleft} -\# The interface is \verb|UP|. IPv6 started stateless autoconfiguration itself,\\ -\# and its configuration finishes here. However,\\ -\# IP still needs some static preconfigured address. -\end{flushleft} -\begin{verbatim} -if [ "$ipaddr" = "" ]; then - echo "No address for $dev is configured, trying DHCP..." 1>&2 - dhcpcd - exit $? -fi -\end{verbatim} - -\begin{flushleft} -\# {\bf Step 2} --- IP Duplicate Address Detection~\cite{RFC-DHCP}.\\ -\# Send two probes and wait for result for 3 seconds.\\ -\# If the interface opens slower f.e.\ due to long media detection,\\ -\# you want to increase the timeout.\\ -\end{flushleft} -\begin{verbatim} -if ! arping -q -c 2 -w 3 -D -I $dev $ipaddr ; then - echo "Address $ipaddr is busy, trying DHCP..." 1>&2 - dhcpcd - exit $? -fi -\end{verbatim} -\begin{flushleft} -\# OK, the address is unique, we may add it on the interface.\\ -\#\\ -\# {\bf Step 3} --- Configure the address on the interface. -\end{flushleft} - -\begin{verbatim} -if ! ip address add $pfx brd + dev $dev; then - echo "Failed to add $pfx on $dev, trying DHCP..." 1>&2 - dhcpcd - exit $? -fi -\end{verbatim} - -\noindent\# {\bf Step 4} --- Announce our presence on the link. -\begin{verbatim} -arping -A -c 1 -I $dev $ipaddr -noarp=$? -( sleep 2; - arping -U -c 1 -I $dev $ipaddr ) >& /dev/null </dev/null & -\end{verbatim} - -\begin{flushleft} -\# {\bf Step 5} (optional) --- Add some control routes.\\ -\#\\ -\# 1. Prohibit link local multicast addresses.\\ -\# 2. Prohibit link local (alias, limited) broadcast.\\ -\# 3. Add default multicast route. -\end{flushleft} -\begin{verbatim} -ip route add unreachable 224.0.0.0/24 -ip route add unreachable 255.255.255.255 -if [ `ip link ls $dev | grep -c MULTICAST` -ge 1 ]; then - ip route add 224.0.0.0/4 dev $dev scope global -fi -\end{verbatim} - -\begin{flushleft} -\# {\bf Step 6} --- Add fallback default route with huge metric.\\ -\# If a proxy ARP server is present on the interface, we will be\\ -\# able to talk to all the Internet without further configuration.\\ -\# It is not so cheap though and we still hope that this route\\ -\# will be overridden by more correct one by rdisc.\\ -\# Do not make this step if the device is not ARPable,\\ -\# because dead nexthop detection does not work on them. -\end{flushleft} -\begin{verbatim} -if [ "$noarp" = "0" ]; then - ip ro add default dev $dev metric 30000 scope global -fi -\end{verbatim} - -\begin{flushleft} -\# {\bf Step 7} --- Restart router discovery and exit. -\end{flushleft} -\begin{verbatim} -killall -HUP rdisc || rdisc -fs -exit 0 -\end{verbatim} - - -\section{Example: {\protect\tt ifcfg} --- interface address management} -\label{EXAMPLE-IFCFG} - -This is a simplistic script replacing one option of \verb|ifconfig|, -namely, IP address management. It not only adds -addresses, but also carries out Duplicate Address Detection~\cite{RFC-DHCP}, -sends unsolicited ARP to update the caches of other hosts sharing -the interface, adds some control routes and restarts Router Discovery -when it is necessary. - -I strongly recommend using it {\em instead\/} of \verb|ifconfig| both -on hosts and on routers. - -\begin{verbatim} -#! /bin/bash -\end{verbatim} -\begin{flushleft} -\# {\bf Usage: \verb?ifcfg DEVICE[:ALIAS] [add|del] ADDRESS[/LENGTH] [PEER]?}\\ -\# {\bf Parameters:}\\ -\# ---Device name. It may have alias suffix, separated by colon.\\ -\# ---Command: add, delete or stop.\\ -\# ---IP address, optionally followed by prefix length.\\ -\# ---Optional peer address for pointopoint interfaces.\\ -\# F.e. \verb|ifcfg eth0 193.233.7.90/24| - -\noindent\# This function determines, whether it is router or host.\\ -\# It returns 0, if the host is apparently not router. -\end{flushleft} -\begin{verbatim} -CheckForwarding () { - local sbase fwd - sbase=/proc/sys/net/ipv4/conf - fwd=0 - if [ -d $sbase ]; then - for dir in $sbase/*/forwarding; do - fwd=$[$fwd + `cat $dir`] - done - else - fwd=2 - fi - return $fwd -} -\end{verbatim} -\begin{flushleft} -\# This function restarts Router Discovery.\\ -\end{flushleft} -\begin{verbatim} -RestartRDISC () { - killall -HUP rdisc || rdisc -fs -} -\end{verbatim} -\begin{flushleft} -\# Calculate ABC "natural" mask length\\ -\# Arg: \$1 = dotquad address -\end{flushleft} -\begin{verbatim} -ABCMaskLen () { - local class; - class=${1%%.*} - if [ $class -eq 0 -o $class -ge 224 ]; then return 0 - elif [ $class -ge 192 ]; then return 24 - elif [ $class -ge 128 ]; then return 16 - else return 8 ; fi -} -\end{verbatim} - - -\begin{flushleft} -\# {\bf MAIN()}\\ -\#\\ -\# Strip alias suffix separated by colon. -\end{flushleft} -\begin{verbatim} -label="label $1" -ldev=$1 -dev=${1%:*} -if [ "$dev" = "" -o "$1" = "help" ]; then - echo "Usage: ifcfg DEV [[add|del [ADDR[/LEN]] [PEER] | stop]" 1>&2 - echo " add - add new address" 1>&2 - echo " del - delete address" 1>&2 - echo " stop - completely disable IP" 1>&2 - exit 1 -fi -shift - -CheckForwarding -fwd=$? -\end{verbatim} -\begin{flushleft} -\# Parse command. If it is ``stop'', flush and exit. -\end{flushleft} -\begin{verbatim} -deleting=0 -case "$1" in -add) shift ;; -stop) - if [ "$ldev" != "$dev" ]; then - echo "Cannot stop alias $ldev" 1>&2 - exit 1; - fi - ip -4 addr flush dev $dev $label || exit 1 - if [ $fwd -eq 0 ]; then RestartRDISC; fi - exit 0 ;; -del*) - deleting=1; shift ;; -*) -esac -\end{verbatim} -\begin{flushleft} -\# Parse prefix, split prefix length, separated by slash. -\end{flushleft} -\begin{verbatim} -ipaddr= -pfxlen= -if [ "$1" != "" ]; then - ipaddr=${1%/*} - if [ "$1" != "$ipaddr" ]; then - pfxlen=${1#*/} - fi - if [ "$ipaddr" = "" ]; then - echo "$1 is bad IP address." 1>&2 - exit 1 - fi -fi -shift -\end{verbatim} -\begin{flushleft} -\# If peer address is present, prefix length is 32.\\ -\# Otherwise, if prefix length was not given, guess it. -\end{flushleft} -\begin{verbatim} -peer=$1 -if [ "$peer" != "" ]; then - if [ "$pfxlen" != "" -a "$pfxlen" != "32" ]; then - echo "Peer address with non-trivial netmask." 1>&2 - exit 1 - fi - pfx="$ipaddr peer $peer" -else - if [ "$pfxlen" = "" ]; then - ABCMaskLen $ipaddr - pfxlen=$? - fi - pfx="$ipaddr/$pfxlen" -fi -if [ "$ldev" = "$dev" -a "$ipaddr" != "" ]; then - label= -fi -\end{verbatim} -\begin{flushleft} -\# If deletion was requested, delete the address and restart RDISC -\end{flushleft} -\begin{verbatim} -if [ $deleting -ne 0 ]; then - ip addr del $pfx dev $dev $label || exit 1 - if [ $fwd -eq 0 ]; then RestartRDISC; fi - exit 0 -fi -\end{verbatim} -\begin{flushleft} -\# Start interface initialization.\\ -\#\\ -\# {\bf Step 0} --- enable device \verb|$dev| -\end{flushleft} -\begin{verbatim} -if ! ip link set up dev $dev ; then - echo "Error: cannot enable interface $dev." 1>&2 - exit 1 -fi -if [ "$ipaddr" = "" ]; then exit 0; fi -\end{verbatim} -\begin{flushleft} -\# {\bf Step 1} --- IP Duplicate Address Detection~\cite{RFC-DHCP}.\\ -\# Send two probes and wait for result for 3 seconds.\\ -\# If the interface opens slower f.e.\ due to long media detection,\\ -\# you want to increase the timeout.\\ -\end{flushleft} -\begin{verbatim} -if ! arping -q -c 2 -w 3 -D -I $dev $ipaddr ; then - echo "Error: some host already uses address $ipaddr on $dev." 1>&2 - exit 1 -fi -\end{verbatim} -\begin{flushleft} -\# OK, the address is unique. We may add it to the interface.\\ -\#\\ -\# {\bf Step 2} --- Configure the address on the interface. -\end{flushleft} -\begin{verbatim} -if ! ip address add $pfx brd + dev $dev $label; then - echo "Error: failed to add $pfx on $dev." 1>&2 - exit 1 -fi -\end{verbatim} -\noindent\# {\bf Step 3} --- Announce our presence on the link -\begin{verbatim} -arping -q -A -c 1 -I $dev $ipaddr -noarp=$? -( sleep 2 ; - arping -q -U -c 1 -I $dev $ipaddr ) >& /dev/null </dev/null & -\end{verbatim} -\begin{flushleft} -\# {\bf Step 4} (optional) --- Add some control routes.\\ -\#\\ -\# 1. Prohibit link local multicast addresses.\\ -\# 2. Prohibit link local (alias, limited) broadcast.\\ -\# 3. Add default multicast route. -\end{flushleft} -\begin{verbatim} -ip route add unreachable 224.0.0.0/24 >& /dev/null -ip route add unreachable 255.255.255.255 >& /dev/null -if [ `ip link ls $dev | grep -c MULTICAST` -ge 1 ]; then - ip route add 224.0.0.0/4 dev $dev scope global >& /dev/null -fi -\end{verbatim} -\begin{flushleft} -\# {\bf Step 5} --- Add fallback default route with huge metric.\\ -\# If a proxy ARP server is present on the interface, we will be\\ -\# able to talk to all the Internet without further configuration.\\ -\# Do not make this step on router or if the device is not ARPable.\\ -\# because dead nexthop detection does not work on them. -\end{flushleft} -\begin{verbatim} -if [ $fwd -eq 0 ]; then - if [ $noarp -eq 0 ]; then - ip ro append default dev $dev metric 30000 scope global - elif [ "$peer" != "" ]; then - if ping -q -c 2 -w 4 $peer ; then - ip ro append default via $peer dev $dev metric 30001 - fi - fi - RestartRDISC -fi - -exit 0 -\end{verbatim} -\begin{flushleft} -\# End of {\bf MAIN()} -\end{flushleft} - - -\end{document} diff --git a/doc/ip-tunnels.tex b/doc/ip-tunnels.tex deleted file mode 100644 index 0a8c930..0000000 --- a/doc/ip-tunnels.tex +++ /dev/null @@ -1,469 +0,0 @@ -\documentstyle[12pt,twoside]{article} -\def\TITLE{Tunnels over IP} -\input preamble -\begin{center} -\Large\bf Tunnels over IP in Linux-2.2 -\end{center} - - -\begin{center} -{ \large Alexey~N.~Kuznetsov } \\ -\em Institute for Nuclear Research, Moscow \\ -\verb|kuznet@ms2.inr.ac.ru| \\ -\rm March 17, 1999 -\end{center} - -\vspace{5mm} - -\tableofcontents - - -\section{Instead of introduction: micro-FAQ.} - -\begin{itemize} - -\item -Q: In linux-2.0.36 I used: -\begin{verbatim} - ifconfig tunl1 10.0.0.1 pointopoint 193.233.7.65 -\end{verbatim} -to create tunnel. It does not work in 2.2.0! - -A: You are right, it does not work. The command written above is split to two commands. -\begin{verbatim} - ip tunnel add MY-TUNNEL mode ipip remote 193.233.7.65 -\end{verbatim} -will create tunnel device with name \verb|MY-TUNNEL|. Now you may configure -it with: -\begin{verbatim} - ifconfig MY-TUNNEL 10.0.0.1 -\end{verbatim} -Certainly, if you prefer name \verb|tunl1| to \verb|MY-TUNNEL|, -you still may use it. - -\item -Q: In linux-2.0.36 I used: -\begin{verbatim} - ifconfig tunl0 10.0.0.1 - route add -net 10.0.0.0 gw 193.233.7.65 dev tunl0 -\end{verbatim} -to tunnel net 10.0.0.0 via router 193.233.7.65. It does not -work in 2.2.0! Moreover, \verb|route| prints a funny error sort of -``network unreachable'' and after this I found a strange direct route -to 10.0.0.0 via \verb|tunl0| in routing table. - -A: Yes, in 2.2 the rule that {\em normal} gateway must reside on directly -connected network has not any exceptions. You may tell kernel, that -this particular route is {\em abnormal}: -\begin{verbatim} - ifconfig tunl0 10.0.0.1 netmask 255.255.255.255 - ip route add 10.0.0.0/8 via 193.233.7.65 dev tunl0 onlink -\end{verbatim} -Note keyword \verb|onlink|, it is the magic key that orders kernel -not to check for consistency of gateway address. -Probably, after this explanation you have already guessed another method -to cheat kernel: -\begin{verbatim} - ifconfig tunl0 10.0.0.1 netmask 255.255.255.255 - route add -host 193.233.7.65 dev tunl0 - route add -net 10.0.0.0 netmask 255.0.0.0 gw 193.233.7.65 - route del -host 193.233.7.65 dev tunl0 -\end{verbatim} -Well, if you like such tricks, nobody may prohibit you to use them. -Only do not forget -that between \verb|route add| and \verb|route del| host 193.233.7.65 is -unreachable. - -\item -Q: In 2.0.36 I used to load \verb|tunnel| device module and \verb|ipip| module. -I cannot find any \verb|tunnel| in 2.2! - -A: Linux-2.2 has single module \verb|ipip| for both directions of tunneling -and for all IPIP tunnel devices. - -\item -Q: \verb|traceroute| does not work over tunnel! Well, stop... It works, - only skips some number of hops. - -A: Yes. By default tunnel driver copies \verb|ttl| value from -inner packet to outer one. It means that path traversed by tunneled -packets to another endpoint is not hidden. If you dislike this, or if you -are going to use some routing protocol expecting that packets -with ttl 1 will reach peering host (f.e.\ RIP, OSPF or EBGP) -and you are not afraid of -tunnel loops, you may append option \verb|ttl 64|, when creating tunnel -with \verb|ip tunnel add|. - -\item -Q: ... Well, list of things, which 2.0 was able to do finishes. - -\end{itemize} - -\paragraph{Summary of differences between 2.2 and 2.0.} - -\begin{itemize} - -\item {\bf In 2.0} you could compile tunnel device into kernel - and got set of 4 devices \verb|tunl0| ... \verb|tunl3| or, - alternatively, compile it as module and load new module - for each new tunnel. Also, module \verb|ipip| was necessary - to receive tunneled packets. - - {\bf 2.2} has {\em one\/} module \verb|ipip|. Loading it you get base - tunnel device \verb|tunl0| and another tunnels may be created with command - \verb|ip tunnel add|. These new devices may have arbitrary names. - - -\item {\bf In 2.0} you set remote tunnel endpoint address with - the command \verb|ifconfig| ... \verb|pointopoint A|. - - {\bf In 2.2} this command has the same semantics on all - the interfaces, namely it sets not tunnel endpoint, - but address of peering host, which is directly reachable - via this tunnel, - rather than via Internet. Actual tunnel endpoint address \verb|A| - should be set with \verb|ip tunnel add ... remote A|. - -\item {\bf In 2.0} you create tunnel routes with the command: -\begin{verbatim} - route add -net 10.0.0.0 gw A dev tunl0 -\end{verbatim} - - {\bf 2.2} interprets this command equally for all device - kinds and gateway is required to be directly reachable via this tunnel, - rather than via Internet. You still may use \verb|ip route add ... onlink| - to override this behaviour. - -\end{itemize} - - -\section{Tunnel setup: basics} - -Standard Linux-2.2 kernel supports three flavor of tunnels, -listed in the following table: -\vspace{2mm} - -\begin{tabular}{lll} -\vrule depth 0.8ex width 0pt\relax -Mode & Description & Base device \\ -ipip & IP over IP & tunl0 \\ -sit & IPv6 over IP & sit0 \\ -gre & ANY over GRE over IP & gre0 -\end{tabular} - -\vspace{2mm} - -\noindent All the kinds of tunnels are created with one command: -\begin{verbatim} - ip tunnel add <NAME> mode <MODE> [ local <S> ] [ remote <D> ] -\end{verbatim} - -This command creates new tunnel device with name \verb|<NAME>|. -The \verb|<NAME>| is an arbitrary string. Particularly, -it may be even \verb|eth0|. The rest of parameters set -different tunnel characteristics. - -\begin{itemize} - -\item -\verb|mode <MODE>| sets tunnel mode. Three modes are available now - \verb|ipip|, \verb|sit| and \verb|gre|. - -\item -\verb|remote <D>| sets remote endpoint of the tunnel to IP - address \verb|<D>|. -\item -\verb|local <S>| sets fixed local address for tunneled - packets. It must be an address on another interface of this host. - -\end{itemize} - -\let\thefootnote\oldthefootnote - -Both \verb|remote| and \verb|local| may be omitted. In this case we -say that they are zero or wildcard. Two tunnels of one mode cannot -have the same \verb|remote| and \verb|local|. Particularly it means -that base device or fallback tunnel cannot be replicated.\footnote{ -This restriction is relaxed for keyed GRE tunnels.} - -Tunnels are divided to two classes: {\bf pointopoint} tunnels, which -have some not wildcard \verb|remote| address and deliver all the packets -to this destination, and {\bf NBMA} (i.e. Non-Broadcast Multi-Access) tunnels, -which have no \verb|remote|. Particularly, base devices (f.e.\ \verb|tunl0|) -are NBMA, because they have neither \verb|remote| nor -\verb|local| addresses. - - -After tunnel device is created you should configure it as you did -it with another devices. Certainly, the configuration of tunnels has -some features related to the fact that they work over existing Internet -routing infrastructure and simultaneously create new virtual links, -which changes this infrastructure. The danger that not enough careful -tunnel setup will result in formation of tunnel loops, -collapse of routing or flooding network with exponentially -growing number of tunneled fragments is very real. - - -Protocol setup on pointopoint tunnels does not differ of configuration -of another devices. You should set a protocol address with \verb|ifconfig| -and add routes with \verb|route| utility. - -NBMA tunnels are different. To route something via NBMA tunnel -you have to explain to driver, where it should deliver packets to. -The only way to make it is to create special routes with gateway -address pointing to desired endpoint. F.e.\ -\begin{verbatim} - ip route add 10.0.0.0/24 via <A> dev tunl0 onlink -\end{verbatim} -It is important to use option \verb|onlink|, otherwise -kernel will refuse request to create route via gateway not directly -reachable over device \verb|tunl0|. With IPv6 the situation is much simpler: -when you start device \verb|sit0|, it automatically configures itself -with all IPv4 addresses mapped to IPv6 space, so that all IPv4 -Internet is {\em really reachable} via \verb|sit0|! Excellent, the command -\begin{verbatim} - ip route add 3FFE::/16 via ::193.233.7.65 dev sit0 -\end{verbatim} -will route \verb|3FFE::/16| via \verb|sit0|, sending all the packets -destined to this prefix to 193.233.7.65. - -\section{Tunnel setup: options} - -Command \verb|ip tunnel add| has several additional options. -\begin{itemize} - -\item \verb|ttl N| --- set fixed TTL \verb|N| on tunneled packets. - \verb|N| is number in the range 1--255. 0 is special value, - meaning that packets inherit TTL value. - Default value is: \verb|inherit|. - -\item \verb|tos T| --- set fixed tos \verb|T| on tunneled packets. - Default value is: \verb|inherit|. - -\item \verb|dev DEV| --- bind tunnel to device \verb|DEV|, so that - tunneled packets will be routed only via this device and will - not be able to escape to another device, when route to endpoint changes. - -\item \verb|nopmtudisc| --- disable Path MTU Discovery on this tunnel. - It is enabled by default. Note that fixed ttl is incompatible - with this option: tunnels with fixed ttl always make pmtu discovery. - -\end{itemize} - -\verb|ipip| and \verb|sit| tunnels have no more options. \verb|gre| -tunnels are more complicated: - -\begin{itemize} - -\item \verb|key K| --- use keyed GRE with key \verb|K|. \verb|K| is - either number or IP address-like dotted quad. - -\item \verb|csum| --- checksum tunneled packets. - -\item \verb|seq| --- serialize packets. -\begin{NB} - I think this option does not - work. At least, I did not test it, did not debug it and - even do not understand, how it is supposed to work and for what - purpose Cisco planned to use it. -\end{NB} - -\end{itemize} - - -Actually, these GRE options can be set separately for input and -output directions by prefixing corresponding keywords with letter -\verb|i| or \verb|o|. F.e.\ \verb|icsum| orders to accept only -packets with correct checksum and \verb|ocsum| means, that -our host will calculate and send checksum. - -Command \verb|ip tunnel add| is not the only operation, -which can be made with tunnels. Certainly, you may get short help page -with: -\begin{verbatim} - ip tunnel help -\end{verbatim} - -Besides that, you may view list of installed tunnels with the help of command: -\begin{verbatim} - ip tunnel ls -\end{verbatim} -Also you may look at statistics: -\begin{verbatim} - ip -s tunnel ls Cisco -\end{verbatim} -where \verb|Cisco| is name of tunnel device. Command -\begin{verbatim} - ip tunnel del Cisco -\end{verbatim} -destroys tunnel \verb|Cisco|. And, finally, -\begin{verbatim} - ip tunnel change Cisco mode sit local ME remote HE ttl 32 -\end{verbatim} -changes its parameters. - -\section{Differences 2.2 and 2.0 tunnels revisited.} - -Now we can discuss more subtle differences between tunneling in 2.0 -and 2.2. - -\begin{itemize} - -\item In 2.0 all tunneled packets were received promiscuously -as soon as you loaded module \verb|ipip|. 2.2 tries to select the best -tunnel device and packet looks as received on this. F.e.\ if host -received \verb|ipip| packet from host \verb|D| destined to our -local address \verb|S|, kernel searches for matching tunnels -in order: - -\begin{tabular}{ll} -1 & \verb|remote| is \verb|D| and \verb|local| is \verb|S| \\ -2 & \verb|remote| is \verb|D| and \verb|local| is wildcard \\ -3 & \verb|remote| is wildcard and \verb|local| is \verb|S| \\ -4 & \verb|tunl0| -\end{tabular} - -If tunnel exists, but it is not in \verb|UP| state, the tunnel is ignored. -Note, that if \verb|tunl0| is \verb|UP| it receives all the IPIP packets, -not acknowledged by more specific tunnels. -Be careful, it means that without carefully installed firewall rules -anyone on the Internet may inject to your network any packets with -source addresses indistinguishable from local ones. It is not so bad idea -to design tunnels in the way enforcing maximal route symmetry -and to enable reversed path filter (\verb|rp_filter| sysctl option) on -tunnel devices. - -\item In 2.2 you can monitor and debug tunnels with \verb|tcpdump|. -F.e.\ \verb|tcpdump| \verb|-i Cisco| \verb|-nvv| will dump packets, -which kernel output, via tunnel \verb|Cisco| and the packets received on it -from kernel viewpoint. - -\end{itemize} - - -\section{Linux and Cisco IOS tunnels.} - -Among another tunnels Cisco IOS supports IPIP and GRE. -Essentially, Cisco setup is subset of options, available for Linux. -Let us consider the simplest example: - -\begin{verbatim} -interface Tunnel0 - tunnel mode gre ip - tunnel source 10.10.14.1 - tunnel destination 10.10.13.2 -\end{verbatim} - - -This command set translates to: - -\begin{verbatim} - ip tunnel add Tunnel0 \ - mode gre \ - local 10.10.14.1 \ - remote 10.10.13.2 -\end{verbatim} - -Any questions? No questions. - -\section{Interaction IPIP tunnels and DVMRP.} - -DVMRP exploits IPIP tunnels to route multicasts via Internet. -\verb|mrouted| creates -IPIP tunnels listed in its configuration file automatically. -From kernel and user viewpoints there are no differences between -tunnels, created in this way, and tunnels created by \verb|ip tunnel|. -I.e.\ if \verb|mrouted| created some tunnel, it may be used to -route unicast packets, provided appropriate routes are added. -And vice versa, if administrator has already created a tunnel, -it will be reused by \verb|mrouted|, if it requests DVMRP -tunnel with the same local and remote addresses. - -Do not wonder, if your manually configured tunnel is -destroyed, when mrouted exits. - - -\section{Broadcast GRE ``tunnels''.} - -It is possible to set \verb|remote| for GRE tunnel to a multicast -address. Such tunnel becomes {\bf broadcast} tunnel (though word -tunnel is not quite appropriate in this case, it is rather virtual network). -\begin{verbatim} - ip tunnel add Universe local 193.233.7.65 \ - remote 224.66.66.66 ttl 16 - ip addr add 10.0.0.1/16 dev Universe - ip link set Universe up -\end{verbatim} -This tunnel is true broadcast network and broadcast packets are -sent to multicast group 224.66.66.66. By default such tunnel starts -to resolve both IP and IPv6 addresses via ARP/NDISC, so that -if multicast routing is supported in surrounding network, all GRE nodes -will find one another automatically and will form virtual Ethernet-like -broadcast network. If multicast routing does not work, it is unpleasant -but not fatal flaw. The tunnel becomes NBMA rather than broadcast network. -You may disable dynamic ARPing by: -\begin{verbatim} - echo 0 > /proc/sys/net/ipv4/neigh/Universe/mcast_solicit -\end{verbatim} -and to add required information to ARP tables manually: -\begin{verbatim} - ip neigh add 10.0.0.2 lladdr 128.6.190.2 dev Universe nud permanent -\end{verbatim} -In this case packets sent to 10.0.0.2 will be encapsulated in GRE -and sent to 128.6.190.2. It is possible to facilitate address resolution -using methods typical for another NBMA networks f.e.\ to start user -level \verb|arpd| daemon, which will maintain database of hosts attached -to GRE virtual network or ask for information -dedicated ARP or NHRP server. - - -Actually, such setup is the most natural for tunneling, -it is really flexible, scalable and easily managable, so that -it is strongly recommended to be used with GRE tunnels instead of ugly -hack with NBMA mode and \verb|onlink| modifier. Unfortunately, -by historical reasons broadcast mode is not supported by IPIP tunnels, -but this probably will change in future. - - - -\section{Traffic control issues.} - -Tunnels are devices, hence all the power of Linux traffic control -applies to them. The simplest (and the most useful in practice) -example is limiting tunnel bandwidth. The following command: -\begin{verbatim} - tc qdisc add dev tunl0 root tbf \ - rate 128Kbit burst 4K limit 10K -\end{verbatim} -will limit tunneled traffic to 128Kbit with maximal burst size of 4K -and queuing not more than 10K. - -However, you should remember, that tunnels are {\em virtual} devices -implemented in software and true queue management is impossible for them -just because they have no queues. Instead, it is better to create classes -on real physical interfaces and to map tunneled packets to them. -In general case of dynamic routing you should create such classes -on all outgoing interfaces, or, alternatively, -to use option \verb|dev DEV| to bind tunnel to a fixed physical device. -In the last case packets will be routed only via specified device -and you need to setup corresponding classes only on it. -Though you have to pay for this convenience, -if routing will change, your tunnel will fail. - -Suppose that CBQ class \verb|1:ABC| has been created on device \verb|eth0| -specially for tunnel \verb|Cisco| with endpoints \verb|S| and \verb|D|. -Now you can select IPIP packets with addresses \verb|S| and \verb|D| -with some classifier and map them to class \verb|1:ABC|. F.e.\ -it is easy to make with \verb|rsvp| classifier: -\begin{verbatim} - tc filter add dev eth0 pref 100 proto ip rsvp \ - session D ipproto ipip filter S \ - classid 1:ABC -\end{verbatim} - -If you want to make more detailed classification of sub-flows -transmitted via tunnel, you can build CBQ subtree, -rooted at \verb|1:ABC| and attach to subroot set of rules parsing -IPIP packets more deeply. - -\end{document} diff --git a/doc/nstat.sgml b/doc/nstat.sgml deleted file mode 100644 index be9d8bc..0000000 --- a/doc/nstat.sgml +++ /dev/null @@ -1,110 +0,0 @@ -<!doctype linuxdoc system> - -<article> - -<title>NSTAT, IFSTAT and RTACCT Utilities -<author>Alexey Kuznetosv, <tt/kuznet@ms2.inr.ac.ru/ -<date>some_negative_number, 20 Sep 2001 -<abstract> -<tt/nstat/, <tt/ifstat/ and <tt/rtacct/ are simple tools helping -to monitor kernel snmp counters and network interface statistics. -</abstract> - -<p> These utilities are very similar, so that I describe -them simultaneously, using name <tt/Xstat/ in the places which apply -to all of them. - -<p>The format of the command is: - -<tscreen><verb> - Xstat [ OPTIONS ] [ PATTERN [ PATTERN ... ] ] -</verb></tscreen> - -<p> -<tt/PATTERN/ is shell style pattern, selecting identifier -of SNMP variables or interfaces to show. Variable is displayed -if one of patterns matches its name. If no patterns are given, -<tt/Xstat/ assumes that user wants to see all the variables. - -<p> <tt/OPTIONS/ is list of single letter options, using common unix -conventions. - -<itemize> -<item><tt/-h/ - show help page -<item><tt/-?/ - the same, of course -<item><tt/-v/, <tt/-V/ - print version of <tt/Xstat/ and exit -<item><tt/-z/ - dump zero counters too. By default they are not shown. -<item><tt/-a/ - dump absolute values of counters. By default <tt/Xstat/ - calculates increments since the previous use. -<item><tt/-s/ - do not update history, so that the next time you will - see counters including values accumulated to the moment - of this measurement too. -<item><tt/-n/ - do not display anything, only update history. -<item><tt/-r/ - reset history. -<item><tt/-d INTERVAL/ - <tt/Xstat/ is run in daemon mode collecting - statistics. <tt/INTERVAL/ is interval between measurements - in seconds. -<item><tt/-t INTERVAL/ - time interval to average rates. Default value - is 60 seconds. -<item><tt/-e/ - display extended information about errors (<tt/ifstat/ only). -</itemize> - -<p> -History is just dump saved in file <tt>/tmp/.Xstat.uUID</tt> -or in file given by environment variables <tt/NSTAT_HISTORY/, -<tt/IFSTAT_HISTORY/ and <tt/RTACCT_HISTORY/. -Each time when you use <tt/Xstat/ values there are updated. -If you use patterns, only the values which you _really_ see -are updated. If you want to skip an unintersting period, -use option <tt/-n/, or just output to <tt>/dev/null</tt>. - -<p> -<tt/Xstat/ understands when history is invalidated by system reboot -or source of information switched between different instances -of daemonic <tt/Xstat/ and kernel SNMP tables and does not -use invalid history. - -<p> Beware, <tt/Xstat/ will not produce sane output, -when many processes use it simultaneously. If several processes -under single user need this utility they should use environment -variables to put their history in safe places -or to use it with options <tt/-a -s/. - -<p> -Well, that's all. The utility is very simple, but nevertheless -very handy. - -<p> <bf/Output of XSTAT/ -<p> The first line of output is <tt/#/ followed by identifier -of source of information, it may be word <tt/kernel/, when <tt/Xstat/ -gets information from kernel or some dotted decimal number followed -by parameters, when it obtains information from running <tt/Xstat/ daemon. - -<p>In the case of <tt/nstat/ the rest of output consists of three columns: -SNMP MIB identifier, -its value (or increment since previous measurement) and average -rate of increase of the counter per second. <tt/ifstat/ outputs -interface name followed by pairs of counter and rate of its change. - -<p> <bf/Daemonic Xstat/ -<p> <tt/Xstat/ may be started as daemon by any user. This makes sense -to avoid wrapped counters and to obtain reasonable long counters -for large time. Also <tt/Xstat/ daemon calculates average rates. -For the first goal sampling interval (option <tt/-d/) may be large enough, -f.e. for gigabit rates byte counters overflow not more frequently than -each 40 seconds and you may select interval of 20 seconds. -From the other hand, when <tt/Xstat/ is used for estimating rates -interval should be less than averaging period (option <tt/-t/), otherwise -estimation loses in quality. - -Client <tt/Xstat/, before trying to get information from the kernel, -contacts daemon started by this user, then it tries system wide -daemon, which is supposed to be started by superuser. And only if -none of them replied it gets information from kernel. - -<p> <bf/Environment/ -<p> <tt/NSTAT_HISTORY/ - name of history file for <tt/nstat/. -<p> <tt/IFSTAT_HISTORY/ - name of history file for <tt/ifstat/. -<p> <tt/RTACCT_HISTORY/ - name of history file for <tt/rtacct/. - -</article> diff --git a/doc/preamble.tex b/doc/preamble.tex deleted file mode 100644 index 80ca508..0000000 --- a/doc/preamble.tex +++ /dev/null @@ -1,26 +0,0 @@ -\textwidth 6.0in -\textheight 8.5in - -\input SNAPSHOT - -\pagestyle{myheadings} -\markboth{\protect\TITLE}{} -\markright{{\protect\sc iproute2-ss\Draft}} - -% To print it in compact form: both sides on one sheet (psnup -2) -\evensidemargin=\oddsidemargin - -\newenvironment{NB}{\bgroup \vskip 1mm\leftskip 1cm \footnotesize \noindent NB. -}{\par\egroup \vskip 1mm} - -\def\threeonly{[2.3.15+ only] } - -\begin{document} - -\makeatletter -\renewcommand{\@oddhead}{{\protect\sc iproute2-ss\Draft} \hfill \protect\arabic{page}} -\makeatother -\let\oldthefootnote\thefootnote -\def\thefootnote{} -\footnotetext{Copyright \copyright~1999 A.N.Kuznetsov} - diff --git a/doc/rtstat.sgml b/doc/rtstat.sgml deleted file mode 100644 index 07391c3..0000000 --- a/doc/rtstat.sgml +++ /dev/null @@ -1,52 +0,0 @@ -<!doctype linuxdoc system> - -<article> - -<title>RTACCT Utility -<author>Robert Olsson -<date>some_negative_number, 20 Dec 2001 - -<p> -Here is some code for monitoring the route cache. For systems handling high -network load, servers, routers, firewalls etc the route cache and its garbage -collection is crucial. Linux has a solid implementation. - -<p> -The kernel patch (not required since linux-2.4.7) adds statistics counters -from route cache process into -/proc/net/rt_cache_stat. A companion user mode program presents the statistics -in a vmstat or iostat manner. The ratio between cache hits and misses gives -the flow length. - -<p> -Hopefully it can help understanding performance and DoS and other related -issues. - -<p> An URL where newer versions of this utility can be (probably) found -is ftp://robur.slu.se/pub/Linux/net-development/rt_cache_stat/ - - -<p><bf/Description/ - -<p>The format of the command is: - -<tscreen><verb> - rtstat [ OPTIONS ] -</verb></tscreen> - -<p> <tt/OPTIONS/ are: - -<itemize> - -<item><tt/-h/, <tt/-help/ - show help page and version of the utility. - -<item><tt/-i INTERVAL/ - interval between snapshots, default value is -2 seconds. - -<item><tt/-s NUMBER/ - whether to print header line. 0 inhibits header line, -1 prescribes to print it once and 2 (this is default setting) forces header -line each 20 lines. - -</itemize> - -</article> diff --git a/doc/ss.sgml b/doc/ss.sgml deleted file mode 100644 index 0b1b533..0000000 --- a/doc/ss.sgml +++ /dev/null @@ -1,525 +0,0 @@ -<!doctype linuxdoc system> - -<article> - -<title>SS Utility: Quick Intro -<author>Alexey Kuznetosv, <tt/kuznet@ms2.inr.ac.ru/ -<date>some_negative_number, 20 Sep 2001 -<abstract> -<tt/ss/ is one another utility to investigate sockets. -Functionally it is NOT better than <tt/netstat/ combined -with some perl/awk scripts and though it is surely faster -it is not enough to make it much better. :-) -So, stop reading this now and do not waste your time. -Well, certainly, it proposes some functionality, which current -netstat is still not able to do, but surely will soon. -</abstract> - -<sect>Why? - -<p> <tt>/proc</tt> interface is inadequate, unfortunately. -When amount of sockets is enough large, <tt/netstat/ or even -plain <tt>cat /proc/net/tcp/</tt> cause nothing but pains and curses. -In linux-2.4 the desease became worse: even if amount -of sockets is small reading <tt>/proc/net/tcp/</tt> is slow enough. - -This utility presents a new approach, which is supposed to scale -well. I am not going to describe technical details here and -will concentrate on description of the command. -The only important thing to say is that it is not so bad idea -to load module <tt/tcp_diag/, which can be found in directory -<tt/Modules/ of <tt/iproute2/. If you do not make this <tt/ss/ -will work, but it falls back to <tt>/proc</tt> and becomes slow -like <tt/netstat/, well, a bit faster yet (see section "Some numbers"). - -<sect>Old news - -<p> -In the simplest form <tt/ss/ is equivalent to netstat -with some small deviations. - -<itemize> -<item><tt/ss -t -a/ dumps all TCP sockets -<item><tt/ss -u -a/ dumps all UDP sockets -<item><tt/ss -w -a/ dumps all RAW sockets -<item><tt/ss -x -a/ dumps all UNIX sockets -</itemize> - -<p> -Option <tt/-o/ shows TCP timers state. -Option <tt/-e/ shows some extended information. -Etc. etc. etc. Seems, all the options of netstat related to sockets -are supported. Though not AX.25 and other bizarres. :-) -If someone wants, he can make support for decnet and ipx. -Some rudimentary support for them is already present in iproute2 libutils, -and I will be glad to see these new members. - -<p> -However, standard functionality is a bit different: - -<p> -The first: without option <tt/-a/ sockets in states -<tt/TIME-WAIT/ and <tt/SYN-RECV/ are skipped too. -It is more reasonable default, I think. - -<p> -The second: format of UNIX sockets is different. It coincides -with tcp/udp. Though standard kernel still does not allow to -see write/read queues and peer address of connected UNIX sockets, -the patch doing this exists. - -<p> -The third: default is to dump only TCP sockets, rather than all of the types. - -<p> -The next: by default it does not resolve numeric host addresses (like <tt/ip/)! -Resolving is enabled with option <tt/-r/. Service names, usually stored -in local files, are resolved by default. Also, if service database -does not contain references to a port, <tt/ss/ queries system -<tt/rpcbind/. RPC services are prefixed with <tt/rpc./ -Resolution of services may be suppressed with option <tt/-n/. - -<p> -It does not accept "long" options (I dislike them, sorry). -So, address family is given with family identifier following -option <tt/-f/ to be algined to iproute2 conventions. -Mostly, it is to allow option parser to parse -addresses correctly, but as side effect it really limits dumping -to sockets supporting only given family. Option <tt/-A/ followed -by list of socket tables to dump is also supported. -Logically, id of socket table is different of _address_ family, which is -another point of incompatibility. So, id is one of -<tt/all/, <tt/tcp/, <tt/udp/, -<tt/raw/, <tt/inet/, <tt/unix/, <tt/packet/, <tt/netlink/. See? -Well, <tt/inet/ is just abbreviation for <tt/tcp|udp|raw/ -and it is not difficult to guess that <tt/packet/ allows -to look at packet sockets. Actually, there are also some other abbreviations, -f.e. <tt/unix_dgram/ selects only datagram UNIX sockets. - -<p> -The next: well, I still do not know. :-) - - - - -<sect>Time to talk about new functionality. - -<p>It is builtin filtering of socket lists. - -<sect1> Filtering by state. - -<p> -<tt/ss/ allows to filter socket states, using keywords -<tt/state/ and <tt/exclude/, followed by some state -identifier. - -<p> -State identifier are standard TCP state names (not listed, -they are useless for you if you already do not know them) -or abbreviations: - -<itemize> -<item><tt/all/ - for all the states -<item><tt/bucket/ - for TCP minisockets (<tt/TIME-WAIT|SYN-RECV/) -<item><tt/big/ - all except for minisockets -<item><tt/connected/ - not closed and not listening -<item><tt/synchronized/ - connected and not <tt/SYN-SENT/ -</itemize> - -<p> - F.e. to dump all tcp sockets except <tt/SYN-RECV/: - -<tscreen><verb> - ss exclude SYN-RECV -</verb></tscreen> - -<p> - If neither <tt/state/ nor <tt/exclude/ directives - are present, - state filter defaults to <tt/all/ with option <tt/-a/ - or to <tt/all/, - excluding listening, syn-recv, time-wait and closed sockets. - -<sect1> Filtering by addresses and ports. - -<p> -Option list may contain address/port filter. -It is boolean expression which consists of boolean operation -<tt/or/, <tt/and/, <tt/not/ and predicates. -Actually, all the flavors of names for boolean operations are eaten: -<tt/&/, <tt/&&/, <tt/|/, <tt/||/, <tt/!/, but do not forget -about special sense given to these symbols by unix shells and escape -them correctly, when used from command line. - -<p> -Predicates may be of the folowing kinds: - -<itemize> -<item>A. Address/port match, where address is checked against mask - and port is either wildcard or exact. It is one of: - -<tscreen><verb> - dst prefix:port - src prefix:port - src unix:STRING - src link:protocol:ifindex - src nl:channel:pid -</verb></tscreen> - - Both prefix and port may be absent or replaced with <tt/*/, - which means wildcard. UNIX socket use more powerful scheme - matching to socket names by shell wildcards. Also, prefixes - unix: and link: may be omitted, if address family is evident - from context (with option <tt/-x/ or with <tt/-f unix/ - or with <tt/unix/ keyword) - -<p> - F.e. - -<tscreen><verb> - dst 10.0.0.1 - dst 10.0.0.1: - dst 10.0.0.1/32: - dst 10.0.0.1:* -</verb></tscreen> - are equivalent and mean socket connected to - any port on host 10.0.0.1 - -<tscreen><verb> - dst 10.0.0.0/24:22 -</verb></tscreen> - sockets connected to port 22 on network - 10.0.0.0...255. - -<p> - Note that port separated of address with colon, which creates - troubles with IPv6 addresses. Generally, we interpret the last - colon as splitting port. To allow to give IPv6 addresses, - trick like used in IPv6 HTTP URLs may be used: - -<tscreen><verb> - dst [::1] -</verb></tscreen> - are sockets connected to ::1 on any port - -<p> - Another way is <tt/dst ::1/128/. / helps to understand that - colon is part of IPv6 address. - -<p> - Now we can add another alias for <tt/dst 10.0.0.1/: - <tt/dst [10.0.0.1]/. :-) - -<p> Address may be a DNS name. In this case all the addresses are looked - up (in all the address families, if it is not limited by option <tt/-f/ - or special address prefix <tt/inet:/, <tt/inet6/) and resulting - expression is <tt/or/ over all of them. - -<item> B. Port expressions: -<tscreen><verb> - dport >= :1024 - dport != :22 - sport < :32000 -</verb></tscreen> - etc. - - All the relations: <tt/</, <tt/>/, <tt/=/, <tt/>=/, <tt/=/, <tt/==/, - <tt/!=/, <tt/eq/, <tt/ge/, <tt/lt/, <tt/ne/... - Use variant which you like more, but not forget to escape special - characters when typing them in command line. :-) - - Note that port number syntactically coincides to the case A! - You may even add an IP address, but it will not participate - incomparison, except for <tt/==/ and <tt/!=/, which are equivalent - to corresponding predicates of type A. F.e. -<p> -<tt/dst 10.0.0.1:22/ - is equivalent to <tt/dport eq 10.0.0.1:22/ - and - <tt/not dst 10.0.0.1:22/ is equivalent to - <tt/dport neq 10.0.0.1:22/ - -<item>C. Keyword <tt/autobound/. It matches to sockets bound automatically - on local system. - -</itemize> - - -<sect> Examples - -<p> -<itemize> -<item>1. List all the tcp sockets in state <tt/FIN-WAIT-1/ for our apache - to network 193.233.7/24 and look at their timers: - -<tscreen><verb> - ss -o state fin-wait-1 \( sport = :http or sport = :https \) \ - dst 193.233.7/24 -</verb></tscreen> - - Oops, forgot to say that missing logical operation is - equivalent to <tt/and/. - -<item> 2. Well, now look at the rest... - -<tscreen><verb> - ss -o excl fin-wait-1 - ss state fin-wait-1 \( sport neq :http and sport neq :https \) \ - or not dst 193.233.7/24 -</verb></tscreen> - - Note that we have to do _two_ calls of ss to do this. - State match is always anded to address/port match. - The reason for this is purely technical: ss does fast skip of - not matching states before parsing addresses and I consider the - ability to skip fastly gobs of time-wait and syn-recv sockets - as more important than logical generality. - -<item> 3. So, let's look at all our sockets using autobound ports: - -<tscreen><verb> - ss -a -A all autobound -</verb></tscreen> - - -<item> 4. And eventually find all the local processes connected - to local X servers: - -<tscreen><verb> - ss -xp dst "/tmp/.X11-unix/*" -</verb></tscreen> - - Pardon, this does not work with current kernel, patching is required. - But we still can look at server side: - -<tscreen><verb> - ss -x src "/tmp/.X11-unix/*" -</verb></tscreen> - -</itemize> - - -<sect> Returning to ground: real manual - -<p> -<sect1> Command arguments - -<p> General format of arguments to <tt/ss/ is: - -<tscreen><verb> - ss [ OPTIONS ] [ STATE-FILTER ] [ ADDRESS-FILTER ] -</verb></tscreen> - -<sect2><tt/OPTIONS/ -<p> <tt/OPTIONS/ is list of single letter options, using common unix -conventions. - -<itemize> -<item><tt/-h/ - show help page -<item><tt/-?/ - the same, of course -<item><tt/-v/, <tt/-V/ - print version of <tt/ss/ and exit -<item><tt/-s/ - print summary statistics. This option does not parse -socket lists obtaining summary from various sources. It is useful -when amount of sockets is so huge that parsing <tt>/proc/net/tcp</tt> -is painful. -<item><tt/-D FILE/ - do not display anything, just dump raw information -about TCP sockets to <tt/FILE/ after applying filters. If <tt/FILE/ is <tt/-/ -<tt/stdout/ is used. -<item><tt/-F FILE/ - read continuation of filter from <tt/FILE/. -Each line of <tt/FILE/ is interpreted like single command line option. -If <tt/FILE/ is <tt/-/ <tt/stdin/ is used. -<item><tt/-r/ - try to resolve numeric address/ports -<item><tt/-n/ - do not try to resolve ports -<item><tt/-o/ - show some optional information, f.e. TCP timers -<item><tt/-i/ - show some infomration specific to TCP (RTO, congestion -window, slow start threshould etc.) -<item><tt/-e/ - show even more optional information -<item><tt/-m/ - show extended information on memory used by the socket. -It is available only with <tt/tcp_diag/ enabled. -<item><tt/-p/ - show list of processes owning the socket -<item><tt/-f FAMILY/ - default address family used for parsing addresses. - Also this option limits listing to sockets supporting - given address family. Currently the following families - are supported: <tt/unix/, <tt/inet/, <tt/inet6/, <tt/link/, - <tt/netlink/. -<item><tt/-4/ - alias for <tt/-f inet/ -<item><tt/-6/ - alias for <tt/-f inet6/ -<item><tt/-0/ - alias for <tt/-f link/ -<item><tt/-A LIST-OF-TABLES/ - list of socket tables to dump, separated - by commas. The following identifiers are understood: - <tt/all/, <tt/inet/, <tt/tcp/, <tt/udp/, <tt/raw/, - <tt/unix/, <tt/packet/, <tt/netlink/, <tt/unix_dgram/, - <tt/unix_stream/, <tt/packet_raw/, <tt/packet_dgram/. -<item><tt/-x/ - alias for <tt/-A unix/ -<item><tt/-t/ - alias for <tt/-A tcp/ -<item><tt/-u/ - alias for <tt/-A udp/ -<item><tt/-w/ - alias for <tt/-A raw/ -<item><tt/-a/ - show sockets of all the states. By default sockets - in states <tt/LISTEN/, <tt/TIME-WAIT/, <tt/SYN_RECV/ - and <tt/CLOSE/ are skipped. -<item><tt/-l/ - show only sockets in state <tt/LISTEN/ -</itemize> - -<sect2><tt/STATE-FILTER/ - -<p><tt/STATE-FILTER/ allows to construct arbitrary set of -states to match. Its syntax is sequence of keywords <tt/state/ -and <tt/exclude/ followed by identifier of state. -Available identifiers are: - -<p> -<itemize> -<item> All standard TCP states: <tt/established/, <tt/syn-sent/, -<tt/syn-recv/, <tt/fin-wait-1/, <tt/fin-wait-2/, <tt/time-wait/, -<tt/closed/, <tt/close-wait/, <tt/last-ack/, <tt/listen/ and <tt/closing/. - -<item><tt/all/ - for all the states -<item><tt/connected/ - all the states except for <tt/listen/ and <tt/closed/ -<item><tt/synchronized/ - all the <tt/connected/ states except for -<tt/syn-sent/ -<item><tt/bucket/ - states, which are maintained as minisockets, i.e. -<tt/time-wait/ and <tt/syn-recv/. -<item><tt/big/ - opposite to <tt/bucket/ -</itemize> - -<sect2><tt/ADDRESS_FILTER/ - -<p><tt/ADDRESS_FILTER/ is boolean expression with operations <tt/and/, <tt/or/ -and <tt/not/, which can be abbreviated in C style f.e. as <tt/&/, -<tt/&&/. - -<p> -Predicates check socket addresses, both local and remote. -There are the following kinds of predicates: - -<itemize> -<item> <tt/dst ADDRESS_PATTERN/ - matches remote address and port -<item> <tt/src ADDRESS_PATTERN/ - matches local address and port -<item> <tt/dport RELOP PORT/ - compares remote port to a number -<item> <tt/sport RELOP PORT/ - compares local port to a number -<item> <tt/autobound/ - checks that socket is bound to an ephemeral - port -</itemize> - -<p><tt/RELOP/ is some of <tt/<=/, <tt/>=/, <tt/==/ etc. -To make this more convinient for use in unix shell, alphabetic -FORTRAN-like notations <tt/le/, <tt/gt/ etc. are accepted as well. - -<p>The format and semantics of <tt/ADDRESS_PATTERN/ depends on address -family. - -<itemize> -<item><tt/inet/ - <tt/ADDRESS_PATTERN/ consists of IP prefix, optionally -followed by colon and port. If prefix or port part is absent or replaced -with <tt/*/, this means wildcard match. -<item><tt/inet6/ - The same as <tt/inet/, only prefix refers to an IPv6 -address. Unlike <tt/inet/ colon becomes ambiguous, so that <tt/ss/ allows -to use scheme, like used in URLs, where address is suppounded with -<tt/[/ ... <tt/]/. -<item><tt/unix/ - <tt/ADDRESS_PATTERN/ is shell-style wildcard. -<item><tt/packet/ - format looks like <tt/inet/, only interface index -stays instead of port and link layer protocol id instead of address. -<item><tt/netlink/ - format looks like <tt/inet/, only socket pid -stays instead of port and netlink channel instead of address. -</itemize> - -<p><tt/PORT/ is syntactically <tt/ADDRESS_PATTERN/ with wildcard -address part. Certainly, it is undefined for UNIX sockets. - -<sect1> Environment variables - -<p> -<tt/ss/ allows to change source of information using various -environment variables: - -<p> -<itemize> -<item> <tt/PROC_SLABINFO/ to override <tt>/proc/slabinfo</tt> -<item> <tt/PROC_NET_TCP/ to override <tt>/proc/net/tcp</tt> -<item> <tt/PROC_NET_UDP/ to override <tt>/proc/net/udp</tt> -<item> etc. -</itemize> - -<p> -Variable <tt/PROC_ROOT/ allows to change root of all the <tt>/proc/</tt> -hierarchy. - -<p> -Variable <tt/TCPDIAG_FILE/ prescribes to open a file instead of -requesting kernel to dump information about TCP sockets. - - -<p> This option is used mainly to investigate bug reports, -when dumps of files usually found in <tt>/proc/</tt> are recevied -by e-mail. - -<sect1> Output format - -<p>Six columns. The first is <tt/Netid/, it denotes socket type and -transport protocol, when it is ambiguous: <tt/tcp/, <tt/udp/, <tt/raw/, -<tt/u_str/ is abbreviation for <tt/unix_stream/, <tt/u_dgr/ for UNIX -datagram sockets, <tt/nl/ for netlink, <tt/p_raw/ and <tt/p_dgr/ for -raw and datagram packet sockets. This column is optional, it will -be hidden, if filter selects an unique netid. - -<p> -The second column is <tt/State/. Socket state is displayed here. -The names are standard TCP names, except for <tt/UNCONN/, which -cannot happen for TCP, but normal for not connected sockets -of another types. Again, this column can be hidden. - -<p> -Then two columns (<tt/Recv-Q/ and <tt/Send-Q/) showing amount of data -queued for receive and transmit. - -<p> -And the last two columns display local address and port of the socket -and its peer address, if the socket is connected. - -<p> -If options <tt/-o/, <tt/-e/ or <tt/-p/ were given, options are -displayed not in fixed positions but separated by spaces pairs: -<tt/option:value/. If value is not a single number, it is presented -as list of values, enclosed to <tt/(/ ... <tt/)/ and separated with -commas. F.e. - -<tscreen><verb> - timer:(keepalive,111min,0) -</verb></tscreen> -is typical format for TCP timer (option <tt/-o/). - -<tscreen><verb> - users:((X,113,3)) -</verb></tscreen> -is typical for list of users (option <tt/-p/). - - -<sect>Some numbers - -<p> -Well, let us use <tt/pidentd/ and a tool <tt/ibench/ to measure -its performance. It is 30 requests per second here. Nothing to test, -it is too slow. OK, let us patch pidentd with patch from directory -Patches. After this it handles about 4300 requests per second -and becomes handy tool to pollute socket tables with lots of timewait -buckets. - -<p> -So, each test starts from pollution tables with 30000 sockets -and then doing full dump of the table piped to wc and measuring -timings with time: - -<p>Results: - -<itemize> -<item> <tt/netstat -at/ - 15.6 seconds -<item> <tt/ss -atr/, but without <tt/tcp_diag/ - 5.4 seconds -<item> <tt/ss -atr/ with <tt/tcp_diag/ - 0.47 seconds -</itemize> - -No comments. Though one comment is necessary, most of time -without <tt/tcp_diag/ is wasted inside kernel with completely -blocked networking. More than 10 seconds, yes. <tt/tcp_diag/ -does the same work for 100 milliseconds of system time. - -</article> diff --git a/etc/iproute2/ematch_map b/etc/iproute2/ematch_map deleted file mode 100644 index 7c6a281..0000000 --- a/etc/iproute2/ematch_map +++ /dev/null @@ -1,5 +0,0 @@ -# lookup table for ematch kinds -1 cmp -2 nbyte -3 u32 -4 meta diff --git a/etc/iproute2/rt_dsfield b/etc/iproute2/rt_dsfield deleted file mode 100644 index 110061a..0000000 --- a/etc/iproute2/rt_dsfield +++ /dev/null @@ -1,13 +0,0 @@ -0x10 lowdelay -0x08 throughput -0x04 reliability -# This value overlap with ECT, do not use it! -0x02 mincost -# These values seems do not want to die, Cisco likes them by a strange reason. -0x20 priority -0x40 immediate -0x60 flash -0x80 flash-override -0xa0 critical -0xc0 internet -0xe0 network diff --git a/etc/iproute2/rt_protos b/etc/iproute2/rt_protos deleted file mode 100644 index 5304770..0000000 --- a/etc/iproute2/rt_protos +++ /dev/null @@ -1,29 +0,0 @@ -# -# Reserved protocols. -# -0 unspec -1 redirect -2 kernel -3 boot -4 static -8 gated -9 ra -10 mrt -11 zebra -12 bird -13 dnrouted -14 xorp -15 ntk - -# -# Used by me for gated -# -254 gated/aggr -253 gated/bgp -252 gated/ospf -251 gated/ospfase -250 gated/rip -249 gated/static -248 gated/conn -247 gated/inet -246 gated/default diff --git a/etc/iproute2/rt_realms b/etc/iproute2/rt_realms deleted file mode 100644 index eedd76d..0000000 --- a/etc/iproute2/rt_realms +++ /dev/null @@ -1,13 +0,0 @@ -# -# reserved values -# -0 cosmos -# -# local -# -#1 inr.ac -#2 inr.ruhep -#3 freenet -#4 radio-msu -#5 russia -#6 internet diff --git a/etc/iproute2/rt_scopes b/etc/iproute2/rt_scopes deleted file mode 100644 index 8514bc1..0000000 --- a/etc/iproute2/rt_scopes +++ /dev/null @@ -1,11 +0,0 @@ -# -# reserved values -# -0 global -255 nowhere -254 host -253 link -# -# pseudo-reserved -# -200 site diff --git a/etc/iproute2/rt_tables b/etc/iproute2/rt_tables deleted file mode 100644 index 541abfd..0000000 --- a/etc/iproute2/rt_tables +++ /dev/null @@ -1,11 +0,0 @@ -# -# reserved values -# -255 local -254 main -253 default -0 unspec -# -# local -# -#1 inr.ruhep diff --git a/examples/README.cbq b/examples/README.cbq deleted file mode 100644 index 38c1089..0000000 --- a/examples/README.cbq +++ /dev/null @@ -1,122 +0,0 @@ -# CHANGES -# ------- -# v0.3a2- fixed bug in "if" operator. Thanks kad@dgtu.donetsk.ua. -# v0.3a- added TIME parameter. Example: -# TIME=00:00-19:00;64Kbit/6Kbit -# So, between 00:00 and 19:00 RATE will be 64Kbit. -# Just start "cbq.init timecheck" periodically from cron (every 10 -# minutes for example). -# !!! Anyway you MUST start "cbq.init start" for CBQ initialize. -# v0.2 - Some cosmetique changes. Now it more compatible with -# old bash version. Thanks to Stanislav V. Voronyi -# <stas@cnti.uanet.kharkov.ua>. -# v0.1 - First public release -# -# README -# ------ -# -# First of all - this is just a SIMPLE EXAMPLE of CBQ power. -# Don't ask me "why" and "how" :) -# -# This is an example of using CBQ (Class Based Queueing) and policy-based -# filter for building smart ethernet shapers. All CBQ parameters are -# correct only for ETHERNET (eth0,1,2..) linux interfaces. It works for -# ARCNET too (just set bandwidth parameter to 2Mbit). It was tested -# on 2.1.125-2.1.129 linux kernels (KSI linux, Nostromo version) and -# ip-route utility by A.Kuznetsov (iproute2-ss981101 version). -# You can download ip-route from ftp://ftp.inr.ac.ru/ip-routing or -# get iproute2*.rpm (compiled with glibc) from ftp.ksi-linux.com. -# -# -# HOW IT WORKS -# -# Each shaper must be described by config file in $CBQ_PATH -# (/etc/sysconfig/cbq/) directory - one config file for each CBQ shaper. -# -# Some words about config file name: -# Each shaper has its personal ID - two byte HEX number. Really ID is -# CBQ class. -# So, filename looks like: -# -# cbq-1280.My_first_shaper -# ^^^ ^^^ ^^^^^^^^^^^^^ -# | | |______ Shaper name - any word -# | |___________________ ID (0000-FFFF), let ID looks like shaper's rate -# |______________________ Filename must begin from "cbq-" -# -# -# Config file describes shaper parameters and source[destination] -# address[port]. -# For example let's prepare /etc/sysconfig/cbq/cbq-1280.My_first_shaper: -# -# ----------8<--------------------- -# DEVICE=eth0,10Mbit,1Mbit -# RATE=128Kbit -# WEIGHT=10Kbit -# PRIO=5 -# RULE=192.168.1.0/24 -# ----------8<--------------------- -# -# This is minimal configuration, where: -# DEVICE: eth0 - device where we do control our traffic -# 10Mbit - REAL ethernet card bandwidth -# 1Mbit - "weight" of :1 class (parent for all shapers for eth0), -# as a rule of thumb weight=batdwidth/10. -# 100Mbit adapter's example: DEVICE=eth0,100Mbit,10Mbit -# *** If you want to build more than one shaper per device it's -# enough to describe bandwidth and weight once - cbq.init -# is smart :) You can put only 'DEVICE=eth0' into cbq-* -# config file for eth0. -# -# RATE: Shaper's speed - Kbit,Mbit or bps (bytes per second) -# -# WEIGHT: "weight" of shaper (CBQ class). Like for DEVICE - approx. RATE/10 -# -# PRIO: shaper's priority from 1 to 8 where 1 is the highest one. -# I do always use "5" for all my shapers. -# -# RULE: [source addr][:source port],[dest addr][:dest port] -# Some examples: -# RULE=10.1.1.0/24:80 - all traffic for network 10.1.1.0 to port 80 -# will be shaped. -# RULE=10.2.2.5 - shaper works only for IP address 10.2.2.5 -# RULE=:25,10.2.2.128/25:5000 - all traffic from any address and port 25 to -# address 10.2.2.128 - 10.2.2.255 and port 5000 -# will be shaped. -# RULE=10.5.5.5:80, - shaper active only for traffic from port 80 of -# address 10.5.5.5 -# Multiple RULE fields per one config file are allowed. For example: -# RULE=10.1.1.2:80 -# RULE=10.1.1.2:25 -# RULE=10.1.1.2:110 -# -# *** ATTENTION!!! -# All shapers do work only for outgoing traffic! -# So, if you want to build bidirectional shaper you must set it up for -# both ethernet card. For example let's build shaper for our linux box like: -# -# --------- 192.168.1.1 -# BACKBONE -----eth0-| linux |-eth1------*[our client] -# --------- -# -# Let all traffic from backbone to client will be shaped at 28Kbit and -# traffic from client to backbone - at 128Kbit. We need two config files: -# -# ---8<-----/etc/sysconfig/cbq/cbq-28.client-out---- -# DEVICE=eth1,10Mbit,1Mbit -# RATE=28Kbit -# WEIGHT=2Kbit -# PRIO=5 -# RULE=192.168.1.1 -# ---8<--------------------------------------------- -# -# ---8<-----/etc/sysconfig/cbq/cbq-128.client-in---- -# DEVICE=eth0,10Mbit,1Mbit -# RATE=128Kbit -# WEIGHT=10Kbit -# PRIO=5 -# RULE=192.168.1.1, -# ---8<--------------------------------------------- -# ^pay attention to "," - this is source address! -# -# Enjoy. diff --git a/examples/SYN-DoS.rate.limit b/examples/SYN-DoS.rate.limit deleted file mode 100644 index 8766b67..0000000 --- a/examples/SYN-DoS.rate.limit +++ /dev/null @@ -1,49 +0,0 @@ -#! /bin/sh -x -# -# sample script on using the ingress capabilities -# this script shows how one can rate limit incoming SYNs -# Useful for TCP-SYN attack protection. You can use -# IPchains to have more powerful additions to the SYN (eg -# in addition the subnet) -# -#path to various utilities; -#change to reflect yours. -# -IPROUTE=/root/DS-6-beta/iproute2-990530-dsing -TC=$IPROUTE/tc/tc -IP=$IPROUTE/ip/ip -IPCHAINS=/root/DS-6-beta/ipchains-1.3.9/ipchains -INDEV=eth2 -# -# tag all incoming SYN packets through $INDEV as mark value 1 -############################################################ -$IPCHAINS -A input -i $INDEV -y -m 1 -############################################################ -# -# install the ingress qdisc on the ingress interface -############################################################ -$TC qdisc add dev $INDEV handle ffff: ingress -############################################################ - -# -# -# SYN packets are 40 bytes (320 bits) so three SYNs equals -# 960 bits (approximately 1kbit); so we rate limit below -# the incoming SYNs to 3/sec (not very sueful really; but -#serves to show the point - JHS -############################################################ -$TC filter add dev $INDEV parent ffff: protocol ip prio 50 handle 1 fw \ -police rate 1kbit burst 40 mtu 9k drop flowid :1 -############################################################ - - -# -echo "---- qdisc parameters Ingress ----------" -$TC qdisc ls dev $INDEV -echo "---- Class parameters Ingress ----------" -$TC class ls dev $INDEV -echo "---- filter parameters Ingress ----------" -$TC filter ls dev $INDEV parent ffff: - -#deleting the ingress qdisc -#$TC qdisc del $INDEV ingress diff --git a/examples/cbq.init-v0.7.3 b/examples/cbq.init-v0.7.3 deleted file mode 100644 index 888aba4..0000000 --- a/examples/cbq.init-v0.7.3 +++ /dev/null @@ -1,984 +0,0 @@ -#!/bin/bash -# -# cbq.init v0.7.3 -# Copyright (C) 1999 Pavel Golubev <pg@ksi-linux.com> -# Copyright (C) 2001-2004 Lubomir Bulej <pallas@kadan.cz> -# -# chkconfig: 2345 11 89 -# description: sets up CBQ-based traffic control -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# To get the latest version, check on Freshmeat for actual location: -# -# http://freshmeat.net/projects/cbq.init -# -# -# VERSION HISTORY -# --------------- -# v0.7.3- Deepak Singhal <singhal at users.sourceforge.net> -# - fix timecheck to not ignore regular TIME rules after -# encountering a TIME rule that spans over midnight -# - Nathan Shafer <nicodemus at users.sourceforge.net> -# - allow symlinks to class files -# - Seth J. Blank <antifreeze at users.sourceforge.net> -# - replace hardcoded ip/tc location with variables -# - Mark Davis <mark.davis at gmx.de> -# - allow setting of PRIO_{MARK,RULE,REALM} in class file -# - Fernando Sanch <toptnc at users.sourceforge.net> -# - allow underscores in interface names -# v0.7.2- Paulo Sedrez -# - fix time2abs to allow hours with leading zero in TIME rules -# - Svetlin Simeonov <zvero at yahoo.com> -# - fix cbq_device_list to allow VLAN interfaces -# - Mark Davis <mark.davis at gmx.de> -# - ignore *~ backup files when looking for classes -# - Mike Boyer <boyer at administrative.com> -# - fix to allow arguments to be passed to "restart" command -# v0.7.1- Lubomir Bulej <pallas at kadan.cz> -# - default value for PERTURB -# - fixed small bug in RULE parser to correctly parse rules with -# identical source and destination fields -# - faster initial scanning of DEVICE fields -# v0.7 - Lubomir Bulej <pallas at kadan.cz> -# - lots of various cleanups and reorganizations; the parsing is now -# some 40% faster, but the class ID must be in range 0x0002-0xffff -# (again). Because of the number of internal changes and the above -# class ID restriction, I bumped the version to 0.7 to indicate -# something might have got broken :) -# - changed PRIO_{U32,FW,ROUTE} to PRIO_{RULE,MARK,REALM} -# for consistency with filter keywords -# - exposed "compile" command -# - Catalin Petrescu <taz at dntis.ro> -# - support for port masks in RULE (u32) filter -# - Jordan Vrtanoski <obeliks at mt.net.mk> -# - support for week days in TIME rules -# v0.6.4- Lubomir Bulej <pallas at kadan.cz> -# - added PRIO_* variables to allow easy control of filter priorities -# - added caching to speed up CBQ start, the cache is invalidated -# whenever any of the configuration files changes -# - updated the readme section + some cosmetic fixes -# v0.6.3- Lubomir Bulej <pallas at kadan.cz> -# - removed setup of (unnecessary) class 1:1 - all classes -# now use qdisc's default class 1:0 as their parent -# - minor fix in the timecheck branch - classes -# without leaf qdisc were not updated -# - minor fix to avoid timecheck failure when run -# at time with minutes equal to 08 or 09 -# - respect CBQ_PATH setting in environment -# - made PRIO=5 default, rendering it optional in configs -# - added support for route filter, see notes about REALM keyword -# - added support for fw filter, see notes about MARK keyword -# - added filter display to "list" and "stats" commands -# - readme section update + various cosmetic fixes -# v0.6.2- Catalin Petrescu <taz at dntis.ro> -# - added tunnels interface handling -# v0.6.1- Pavel Golubev <pg at ksi-linux.com> -# - added sch_prio module loading -# (thanks johan at iglo.virtual.or.id for reminding) -# - resolved errors resulting from stricter syntax checking in bash2 -# - Lubomir Bulej <pallas at kadan.cz> -# - various cosmetic fixes -# v0.6 - Lubomir Bulej <pallas at kadan.cz> -# - attempt to limit number of spawned processes by utilizing -# more of sed power (use sed instead of grep+cut) -# - simplified TIME parser, using bash builtins -# - added initial support for SFQ as leaf qdisc -# - reworked the documentation part a little -# - incorporated pending patches and ideas submitted by -# following people for versions 0.3 into version 0.6 -# - Miguel Freitas <miguel at cetuc.puc-rio.br> -# - in case of overlapping TIME parameters, the last match is taken -# - Juanjo Ciarlante <jjo at mendoza.gov.ar> -# - chkconfig tags, list + stats startup parameters -# - optional tc & ip command logging (into /var/run/cbq-*) -# - Rafal Maszkowski <rzm at icm.edu.pl> -# - PEAK parameter for setting TBF's burst peak rate -# - fix for many config files (use find instead of ls) -# v0.5.1- Lubomir Bulej <pallas at kadan.cz> -# - fixed little but serious bug in RULE parser -# v0.5 - Lubomir Bulej <pallas at kadan.cz> -# - added options PARENT, LEAF, ISOLATED and BOUNDED. This allows -# (with some attention to config file ordering) for creating -# hierarchical structures of shapers with classes able (or unable) -# to borrow bandwidth from their parents. -# - class ID check allows hexadecimal numbers -# - rewritten & simplified RULE parser -# - cosmetic changes to improve readability -# - reorganization to avoid duplicate code (timecheck etc.) -# - timecheck doesn't check classes without TIME fields anymore -# v0.4 - Lubomir Bulej <pallas at kadan.cz> -# - small bugfix in RULE parsing code -# - simplified configuration parsing code -# - several small cosmetic changes -# - TIME parameter can be now specified more than once allowing you to -# differentiate RATE throughout the whole day. Time overlapping is -# not checked, first match is taken. Midnight wrap (eg. 20:00-6:00) -# is allowed and taken care of. -# v0.3a4- fixed small bug in IF operator. Thanks to -# Rafal Maszkowski <rzm at icm.edu.pl> -# v0.3a3- fixed grep bug when using more than 10 eth devices. Thanks to David -# Trcka <trcka at poda.cz>. -# v0.3a2- fixed bug in "if" operator. Thanks kad at dgtu.donetsk.ua. -# v0.3a - added TIME parameter. Example: TIME=00:00-19:00;64Kbit/6Kbit -# So, between 00:00 and 19:00 the RATE will be 64Kbit. -# Just start "cbq.init timecheck" periodically from cron -# (every 10 minutes for example). DON'T FORGET though, to run -# "cbq.init start" for CBQ to initialize. -# v0.2 - Some cosmetic changes. Now it is more compatible with old bash -# version. Thanks to Stanislav V. Voronyi <stas at cnti.uanet.kharkov.ua>. -# v0.1 - First public release -# -# -# README -# ------ -# -# First of all - this is just a SIMPLE EXAMPLE of CBQ power. -# Don't ask me "why" and "how" :) -# -# This script is meant to simplify setup and management of relatively simple -# CBQ-based traffic control on Linux. Access to advanced networking features -# of Linux kernel is provided by "ip" and "tc" utilities from A. Kuznetsov's -# iproute2 package, available at ftp://ftp.inr.ac.ru/ip-routing. Because the -# utilities serve primarily to translate user wishes to RTNETLINK commands, -# their interface is rather spartan, intolerant and requires quite a lot of -# typing. And typing is what this script attempts to reduce :) -# -# The advanced networking stuff in Linux is pretty flexible and this script -# aims to bring some of its features to the not-so-hard-core Linux users. Of -# course, there is a tradeoff between simplicity and flexibility and you may -# realize that the flexibility suffered too much for your needs -- time to -# face "ip" and "tc" interface. -# -# To speed up the "start" command, simple caching was introduced in version -# 0.6.4. The caching works so that the sequence of "tc" commands for given -# configuration is stored in a file (/var/cache/cbq.init by default) which -# is used next time the "start" command is run to avoid repeated parsing of -# configuration files. This cache is invalidated whenever any of the CBQ -# configuration files changes. If you want to run "cbq.init start" without -# caching, run it as "cbq.init start nocache". If you want to force cache -# invalidation, run it as "cbq.init start invalidate". Caching is disabled -# if you have logging enabled (ie. CBQ_DEBUG is not empty). -# -# If you only want cqb.init to translate your configuration to "tc" commands, -# use "compile" command which will output "tc" commands required to build -# your configuration. Bear in mind that "compile" does not check if the "tc" -# commands were successful - this is done (in certain places) only when the -# "start nocache" command is used, which is also useful when creating the -# configuration to check whether it is completely valid. -# -# All CBQ parameters are valid for Ethernet interfaces only, The script was -# tested on various Linux kernel versions from series 2.1 to 2.4 and several -# distributions with KSI Linux (Nostromo version) as the premier one. -# -# -# HOW DOES IT WORK? -# ----------------- -# -# Every traffic class must be described by a file in the $CBQ_PATH directory -# (/etc/sysconfig/cbq by default) - one file per class. -# -# The config file names must obey mandatory format: cbq-<clsid>.<name> where -# <clsid> is two-byte hexadecimal number in range <0002-FFFF> (which in fact -# is a CBQ class ID) and <name> is the name of the class -- anything to help -# you distinguish the configuration files. For small amount of classes it is -# often possible (and convenient) to let <clsid> resemble bandwidth of the -# class. -# -# Example of valid config name: -# cbq-1280.My_first_shaper -# -# -# The configuration file may contain the following parameters: -# -### Device parameters -# -# DEVICE=<ifname>,<bandwidth>[,<weight>] mandatory -# DEVICE=eth0,10Mbit,1Mbit -# -# <ifname> is the name of the interface you want to control -# traffic on, e.g. eth0 -# <bandwidth> is the physical bandwidth of the device, e.g. for -# ethernet 10Mbit or 100Mbit, for arcnet 2Mbit -# <weight> is tuning parameter that should be proportional to -# <bandwidth>. As a rule of thumb: <weight> = <bandwidth> / 10 -# -# When you have more classes on one interface, it is enough to specify -# <bandwidth> [and <weight>] only once, therefore in other files you only -# need to set DEVICE=<ifname>. -# -### Class parameters -# -# RATE=<speed> mandatory -# RATE=5Mbit -# -# Bandwidth allocated to the class. Traffic going through the class is -# shaped to conform to specified rate. You can use Kbit, Mbit or bps, -# Kbps and Mbps as suffices. If you don't specify any unit, bits/sec -# are used. Also note that "bps" means "bytes per second", not bits. -# -# WEIGHT=<speed> mandatory -# WEIGHT=500Kbit -# -# Tuning parameter that should be proportional to RATE. As a rule -# of thumb, use WEIGHT ~= RATE / 10. -# -# PRIO=<1-8> optional, default 5 -# PRIO=5 -# -# Priority of class traffic. The higher the number, the lesser -# the priority. Priority of 5 is just fine. -# -# PARENT=<clsid> optional, default not set -# PARENT=1280 -# -# Specifies ID of the parent class to which you want this class be -# attached. You might want to use LEAF=none for the parent class as -# mentioned below. By using this parameter and carefully ordering the -# configuration files, it is possible to create simple hierarchical -# structures of CBQ classes. The ordering is important so that parent -# classes are constructed prior to their children. -# -# LEAF=none|tbf|sfq optional, default "tbf" -# -# Tells the script to attach specified leaf queueing discipline to CBQ -# class. By default, TBF is used. Note that attaching TBF to CBQ class -# shapes the traffic to conform to TBF parameters and prevents the class -# from borrowing bandwidth from its parent even if you have BOUNDED set -# to "no". To allow the class to borrow bandwith (provided it is not -# bounded), you must set LEAF to "none" or "sfq". -# -# If you want to ensure (approximately) fair sharing of bandwidth among -# several hosts in the same class, you might want to specify LEAF=sfq to -# attach SFQ as leaf queueing discipline to that class. -# -# BOUNDED=yes|no optional, default "yes" -# -# If set to "yes", the class is not allowed to borrow bandwidth from -# its parent class in overlimit situation. If set to "no", the class -# will be allowed to borrow bandwidth from its parent. -# -# Note: Don't forget to set LEAF to "none" or "sfq", otherwise the class will -# have TBF attached to itself and will not be able to borrow unused -# bandwith from its parent. -# -# ISOLATED=yes|no optional, default "no" -# -# If set to "yes", the class will not lend unused bandwidth to -# its children. -# -### TBF qdisc parameters -# -# BUFFER=<bytes>[/<bytes>] optional, default "10Kb/8" -# -# This parameter controls the depth of the token bucket. In other -# words it represents the maximal burst size the class can send. -# The optional part of parameter is used to determine the length -# of intervals in packet sizes, for which the transmission times -# are kept. -# -# LIMIT=<bytes> optional, default "15Kb" -# -# This parameter determines the maximal length of backlog. If -# the queue contains more data than specified by LIMIT, the -# newly arriving packets are dropped. The length of backlog -# determines queue latency in case of congestion. -# -# PEAK=<speed> optional, default not set -# -# Maximal peak rate for short-term burst traffic. This allows you -# to control the absolute peak rate the class can send at, because -# single TBF that allows 256Kbit/s would of course allow rate of -# 512Kbit for half a second or 1Mbit for a quarter of second. -# -# MTU=<bytes> optional, default "1500" -# -# Maximum number of bytes that can be sent at once over the -# physical medium. This parameter is required when you specify -# PEAK parameter. It defaults to MTU of ethernet - for other -# media types you might want to change it. -# -# Note: Setting TBF as leaf qdisc will effectively prevent the class from -# borrowing bandwidth from the ancestor class, because even if the -# class allows more traffic to pass through, it is then shaped to -# conform to TBF. -# -### SFQ qdisc parameters -# -# The SFQ queueing discipline is a cheap way for sharing class bandwidth -# among several hosts. As it is stochastic, the fairness is approximate but -# it will do the job in most cases. If you want real fairness, you should -# probably use WRR (weighted round robin) or WFQ queueing disciplines. Note -# that SFQ does not do any traffic shaping - the shaping is done by the CBQ -# class the SFQ is attached to. -# -# QUANTUM=<bytes> optional, default not set -# -# This parameter should not be set lower than link MTU, for ethernet -# it is 1500b, or (with MAC header) 1514b which is the value used -# in Alexey Kuznetsov's examples. -# -# PERTURB=<seconds> optional, default "10" -# -# Period of hash function perturbation. If unset, hash reconfiguration -# will never take place which is what you probably don't want. The -# default value of 10 seconds is probably a good one. -# -### Filter parameters -# -# RULE=[[saddr[/prefix]][:port[/mask]],][daddr[/prefix]][:port[/mask]] -# -# These parameters make up "u32" filter rules that select traffic for -# each of the classes. You can use multiple RULE fields per config. -# -# The optional port mask should only be used by advanced users who -# understand how the u32 filter works. -# -# Some examples: -# -# RULE=10.1.1.0/24:80 -# selects traffic going to port 80 in network 10.1.1.0 -# -# RULE=10.2.2.5 -# selects traffic going to any port on single host 10.2.2.5 -# -# RULE=10.2.2.5:20/0xfffe -# selects traffic going to ports 20 and 21 on host 10.2.2.5 -# -# RULE=:25,10.2.2.128/26:5000 -# selects traffic going from anywhere on port 50 to -# port 5000 in network 10.2.2.128 -# -# RULE=10.5.5.5:80, -# selects traffic going from port 80 of single host 10.5.5.5 -# -# -# -# REALM=[srealm,][drealm] -# -# These parameters make up "route" filter rules that classify traffic -# according to packet source/destination realms. For information about -# realms, see Alexey Kuznetsov's IP Command Reference. This script -# does not define any realms, it justs builds "tc filter" commands -# for you if you need to classify traffic this way. -# -# Realm is either a decimal number or a string referencing entry in -# /etc/iproute2/rt_realms (usually). -# -# Some examples: -# -# REALM=russia,internet -# selects traffic going from realm "russia" to realm "internet" -# -# REALM=freenet, -# selects traffic going from realm "freenet" -# -# REALM=10 -# selects traffic going to realm 10 -# -# -# -# MARK=<mark> -# -# These parameters make up "fw" filter rules that select traffic for -# each of the classes accoring to firewall "mark". Mark is a decimal -# number packets are tagged with if firewall rules say so. You can -# use multiple MARK fields per config. -# -# -# Note: Rules for different filter types can be combined. Attention must be -# paid to the priority of filter rules, which can be set below using -# PRIO_{RULE,MARK,REALM} variables. -# -### Time ranging parameters -# -# TIME=[<dow>,<dow>, ...,<dow>/]<from>-<till>;<rate>/<weight>[/<peak>] -# TIME=0,1,2,5/18:00-06:00;256Kbit/25Kbit -# TIME=60123/18:00-06:00;256Kbit/25Kbit -# TIME=18:00-06:00;256Kbit/25Kbit -# -# This parameter allows you to differentiate the class bandwidth -# throughout the day. You can specify multiple TIME parameters, if -# the times overlap, last match is taken. The fields <rate>, <weight> -# and <peak> correspond to parameters RATE, WEIGHT and PEAK (which -# is optional and applies to TBF leaf qdisc only). -# -# You can also specify days of week when the TIME rule applies. <dow> -# is numeric, 0 corresponds to sunday, 1 corresponds to monday, etc. -# -### -# -# Sample configuration file: cbq-1280.My_first_shaper -# -# -------------------------------------------------------------------------- -# DEVICE=eth0,10Mbit,1Mbit -# RATE=128Kbit -# WEIGHT=10Kbit -# PRIO=5 -# RULE=192.128.1.0/24 -# -------------------------------------------------------------------------- -# -# The configuration says that we will control traffic on 10Mbit ethernet -# device eth0 and the traffic going to network 192.168.1.0 will be -# processed with priority 5 and shaped to rate of 128Kbit. -# -# Note that you can control outgoing traffic only. If you want to control -# traffic in both directions, you must set up CBQ for both interfaces. -# -# Consider the following example: -# -# +---------+ 192.168.1.1 -# BACKBONE -----eth0-| linux |-eth1------*-[client] -# +---------+ -# -# Imagine you want to shape traffic from backbone to the client to 28Kbit -# and traffic in the opposite direction to 128Kbit. You need to setup CBQ -# on both eth0 and eth1 interfaces, thus you need two config files: -# -# cbq-028.backbone-client -# -------------------------------------------------------------------------- -# DEVICE=eth1,10Mbit,1Mbit -# RATE=28Kbit -# WEIGHT=2Kbit -# PRIO=5 -# RULE=192.168.1.1 -# -------------------------------------------------------------------------- -# -# cbq-128.client-backbone -# -------------------------------------------------------------------------- -# DEVICE=eth0,10Mbit,1Mbit -# RATE=128Kbit -# WEIGHT=10Kbit -# PRIO=5 -# RULE=192.168.1.1, -# -------------------------------------------------------------------------- -# -# Pay attention to comma "," in the RULE field - it denotes source address! -# -# Enjoy. -# -############################################################################# - -export LC_ALL=C - -### Command locations -TC=/sbin/tc -IP=/sbin/ip -MP=/sbin/modprobe - -### Default filter priorities (must be different) -PRIO_RULE_DEFAULT=${PRIO_RULE:-100} -PRIO_MARK_DEFAULT=${PRIO_MARK:-200} -PRIO_REALM_DEFAULT=${PRIO_REALM:-300} - -### Default CBQ_PATH & CBQ_CACHE settings -CBQ_PATH=${CBQ_PATH:-/etc/sysconfig/cbq} -CBQ_CACHE=${CBQ_CACHE:-/var/cache/cbq.init} - -### Uncomment to enable logfile for debugging -#CBQ_DEBUG="/var/run/cbq-$1" - -### Modules to probe for. Uncomment the last CBQ_PROBE -### line if you have QoS support compiled into kernel -CBQ_PROBE="sch_cbq sch_tbf sch_sfq sch_prio" -CBQ_PROBE="$CBQ_PROBE cls_fw cls_u32 cls_route" -#CBQ_PROBE="" - -### Keywords required for qdisc & class configuration -CBQ_WORDS="DEVICE|RATE|WEIGHT|PRIO|PARENT|LEAF|BOUNDED|ISOLATED" -CBQ_WORDS="$CBQ_WORDS|PRIO_MARK|PRIO_RULE|PRIO_REALM|BUFFER" -CBQ_WORDS="$CBQ_WORDS|LIMIT|PEAK|MTU|QUANTUM|PERTURB" - -### Source AVPKT if it exists -[ -r /etc/sysconfig/cbq/avpkt ] && . /etc/sysconfig/cbq/avpkt -AVPKT=${AVPKT:-3000} - - -############################################################################# -############################# SUPPORT FUNCTIONS ############################# -############################################################################# - -### Get list of network devices -cbq_device_list () { - ip link show| sed -n "/^[0-9]/ \ - { s/^[0-9]\+: \([a-z0-9._]\+\)[:@].*/\1/; p; }" -} # cbq_device_list - - -### Remove root class from device $1 -cbq_device_off () { - tc qdisc del dev $1 root 2> /dev/null -} # cbq_device_off - - -### Remove CBQ from all devices -cbq_off () { - for dev in `cbq_device_list`; do - cbq_device_off $dev - done -} # cbq_off - - -### Prefixed message -cbq_message () { - echo -e "**CBQ: $@" -} # cbq_message - -### Failure message -cbq_failure () { - cbq_message "$@" - exit 1 -} # cbq_failure - -### Failure w/ cbq-off -cbq_fail_off () { - cbq_message "$@" - cbq_off - exit 1 -} # cbq_fail_off - - -### Convert time to absolute value -cbq_time2abs () { - local min=${1##*:}; min=${min##0} - local hrs=${1%%:*}; hrs=${hrs##0} - echo $[hrs*60 + min] -} # cbq_time2abs - - -### Display CBQ setup -cbq_show () { - for dev in `cbq_device_list`; do - [ `tc qdisc show dev $dev| wc -l` -eq 0 ] && continue - echo -e "### $dev: queueing disciplines\n" - tc $1 qdisc show dev $dev; echo - - [ `tc class show dev $dev| wc -l` -eq 0 ] && continue - echo -e "### $dev: traffic classes\n" - tc $1 class show dev $dev; echo - - [ `tc filter show dev $dev| wc -l` -eq 0 ] && continue - echo -e "### $dev: filtering rules\n" - tc $1 filter show dev $dev; echo - done -} # cbq_show - - -### Check configuration and load DEVICES, DEVFIELDS and CLASSLIST from $1 -cbq_init () { - ### Get a list of configured classes - CLASSLIST=`find $1 \( -type f -or -type l \) -name 'cbq-*' \ - -not -name '*~' -maxdepth 1 -printf "%f\n"| sort` - [ -z "$CLASSLIST" ] && - cbq_failure "no configuration files found in $1!" - - ### Gather all DEVICE fields from $1/cbq-* - DEVFIELDS=`find $1 \( -type f -or -type l \) -name 'cbq-*' \ - -not -name '*~' -maxdepth 1| xargs sed -n 's/#.*//; \ - s/[[:space:]]//g; /^DEVICE=[^,]*,[^,]*\(,[^,]*\)\?/ \ - { s/.*=//; p; }'| sort -u` - [ -z "$DEVFIELDS" ] && - cbq_failure "no DEVICE field found in $1/cbq-*!" - - ### Check for different DEVICE fields for the same device - DEVICES=`echo "$DEVFIELDS"| sed 's/,.*//'| sort -u` - [ `echo "$DEVICES"| wc -l` -ne `echo "$DEVFIELDS"| wc -l` ] && - cbq_failure "different DEVICE fields for single device!\n$DEVFIELDS" -} # cbq_init - - -### Load class configuration from $1/$2 -cbq_load_class () { - CLASS=`echo $2| sed 's/^cbq-0*//; s/^\([0-9a-fA-F]\+\).*/\1/'` - CFILE=`sed -n 's/#.*//; s/[[:space:]]//g; /^[[:alnum:]_]\+=[[:alnum:].,:;/*@-_]\+$/ p' $1/$2` - - ### Check class number - IDVAL=`/usr/bin/printf "%d" 0x$CLASS 2> /dev/null` - [ $? -ne 0 -o $IDVAL -lt 2 -o $IDVAL -gt 65535 ] && - cbq_fail_off "class ID of $2 must be in range <0002-FFFF>!" - - ### Set defaults & load class - RATE=""; WEIGHT=""; PARENT=""; PRIO=5 - LEAF=tbf; BOUNDED=yes; ISOLATED=no - BUFFER=10Kb/8; LIMIT=15Kb; MTU=1500 - PEAK=""; PERTURB=10; QUANTUM="" - - PRIO_RULE=$PRIO_RULE_DEFAULT - PRIO_MARK=$PRIO_MARK_DEFAULT - PRIO_REALM=$PRIO_REALM_DEFAULT - - eval `echo "$CFILE"| grep -E "^($CBQ_WORDS)="` - - ### Require RATE/WEIGHT - [ -z "$RATE" -o -z "$WEIGHT" ] && - cbq_fail_off "missing RATE or WEIGHT in $2!" - - ### Class device - DEVICE=${DEVICE%%,*} - [ -z "$DEVICE" ] && cbq_fail_off "missing DEVICE field in $2!" - - BANDWIDTH=`echo "$DEVFIELDS"| sed -n "/^$DEVICE,/ \ - { s/[^,]*,\([^,]*\).*/\1/; p; q; }"` - - ### Convert to "tc" options - PEAK=${PEAK:+peakrate $PEAK} - PERTURB=${PERTURB:+perturb $PERTURB} - QUANTUM=${QUANTUM:+quantum $QUANTUM} - - [ "$BOUNDED" = "no" ] && BOUNDED="" || BOUNDED="bounded" - [ "$ISOLATED" = "yes" ] && ISOLATED="isolated" || ISOLATED="" -} # cbq_load_class - - -############################################################################# -#################################### INIT ################################### -############################################################################# - -### Check for presence of ip-route2 in usual place -[ -x $TC -a -x $IP ] || - cbq_failure "ip-route2 utilities not installed or executable!" - - -### ip/tc wrappers -if [ "$1" = "compile" ]; then - ### no module probing - CBQ_PROBE="" - - ip () { - $IP "$@" - } # ip - - ### echo-only version of "tc" command - tc () { - echo "$TC $@" - } # tc - -elif [ -n "$CBQ_DEBUG" ]; then - echo -e "# `date`" > $CBQ_DEBUG - - ### Logging version of "ip" command - ip () { - echo -e "\n# ip $@" >> $CBQ_DEBUG - $IP "$@" 2>&1 | tee -a $CBQ_DEBUG - } # ip - - ### Logging version of "tc" command - tc () { - echo -e "\n# tc $@" >> $CBQ_DEBUG - $TC "$@" 2>&1 | tee -a $CBQ_DEBUG - } # tc -else - ### Default wrappers - - ip () { - $IP "$@" - } # ip - - tc () { - $TC "$@" - } # tc -fi # ip/tc wrappers - - -case "$1" in - -############################################################################# -############################### START/COMPILE ############################### -############################################################################# - -start|compile) - -### Probe QoS modules (start only) -for module in $CBQ_PROBE; do - $MP $module || cbq_failure "failed to load module $module" -done - -### If we are in compile/nocache/logging mode, don't bother with cache -if [ "$1" != "compile" -a "$2" != "nocache" -a -z "$CBQ_DEBUG" ]; then - VALID=1 - - ### validate the cache - [ "$2" = "invalidate" -o ! -f $CBQ_CACHE ] && VALID=0 - if [ $VALID -eq 1 ]; then - [ `find $CBQ_PATH -maxdepth 1 -newer $CBQ_CACHE| \ - wc -l` -gt 0 ] && VALID=0 - fi - - ### compile the config if the cache is invalid - if [ $VALID -ne 1 ]; then - $0 compile > $CBQ_CACHE || - cbq_fail_off "failed to compile CBQ configuration!" - fi - - ### run the cached commands - exec /bin/sh $CBQ_CACHE 2> /dev/null -fi - -### Load DEVICES, DEVFIELDS and CLASSLIST -cbq_init $CBQ_PATH - - -### Setup root qdisc on all configured devices -for dev in $DEVICES; do - ### Retrieve device bandwidth and, optionally, weight - DEVTEMP=`echo "$DEVFIELDS"| sed -n "/^$dev,/ { s/$dev,//; p; q; }"` - DEVBWDT=${DEVTEMP%%,*}; DEVWGHT=${DEVTEMP##*,} - [ "$DEVBWDT" = "$DEVWGHT" ] && DEVWGHT="" - - ### Device bandwidth is required - if [ -z "$DEVBWDT" ]; then - cbq_message "could not determine bandwidth for device $dev!" - cbq_failure "please set up the DEVICE fields properly!" - fi - - ### Check if the device is there - ip link show $dev &> /dev/null || - cbq_fail_off "device $dev not found!" - - ### Remove old root qdisc from device - cbq_device_off $dev - - - ### Setup root qdisc + class for device - tc qdisc add dev $dev root handle 1 cbq \ - bandwidth $DEVBWDT avpkt $AVPKT cell 8 - - ### Set weight of the root class if set - [ -n "$DEVWGHT" ] && - tc class change dev $dev root cbq weight $DEVWGHT allot 1514 - - [ "$1" = "compile" ] && echo -done # dev - - -### Setup traffic classes -for classfile in $CLASSLIST; do - cbq_load_class $CBQ_PATH $classfile - - ### Create the class - tc class add dev $DEVICE parent 1:$PARENT classid 1:$CLASS cbq \ - bandwidth $BANDWIDTH rate $RATE weight $WEIGHT prio $PRIO \ - allot 1514 cell 8 maxburst 20 avpkt $AVPKT $BOUNDED $ISOLATED || - cbq_fail_off "failed to add class $CLASS with parent $PARENT on $DEVICE!" - - ### Create leaf qdisc if set - if [ "$LEAF" = "tbf" ]; then - tc qdisc add dev $DEVICE parent 1:$CLASS handle $CLASS tbf \ - rate $RATE buffer $BUFFER limit $LIMIT mtu $MTU $PEAK - elif [ "$LEAF" = "sfq" ]; then - tc qdisc add dev $DEVICE parent 1:$CLASS handle $CLASS sfq \ - $PERTURB $QUANTUM - fi - - - ### Create fw filter for MARK fields - for mark in `echo "$CFILE"| sed -n '/^MARK/ { s/.*=//; p; }'`; do - ### Attach fw filter to root class - tc filter add dev $DEVICE parent 1:0 protocol ip \ - prio $PRIO_MARK handle $mark fw classid 1:$CLASS - done ### mark - - ### Create route filter for REALM fields - for realm in `echo "$CFILE"| sed -n '/^REALM/ { s/.*=//; p; }'`; do - ### Split realm into source & destination realms - SREALM=${realm%%,*}; DREALM=${realm##*,} - [ "$SREALM" = "$DREALM" ] && SREALM="" - - ### Convert asterisks to empty strings - SREALM=${SREALM#\*}; DREALM=${DREALM#\*} - - ### Attach route filter to the root class - tc filter add dev $DEVICE parent 1:0 protocol ip \ - prio $PRIO_REALM route ${SREALM:+from $SREALM} \ - ${DREALM:+to $DREALM} classid 1:$CLASS - done ### realm - - ### Create u32 filter for RULE fields - for rule in `echo "$CFILE"| sed -n '/^RULE/ { s/.*=//; p; }'`; do - ### Split rule into source & destination - SRC=${rule%%,*}; DST=${rule##*,} - [ "$SRC" = "$rule" ] && SRC="" - - - ### Split destination into address, port & mask fields - DADDR=${DST%%:*}; DTEMP=${DST##*:} - [ "$DADDR" = "$DST" ] && DTEMP="" - - DPORT=${DTEMP%%/*}; DMASK=${DTEMP##*/} - [ "$DPORT" = "$DTEMP" ] && DMASK="0xffff" - - - ### Split up source (if specified) - SADDR=""; SPORT="" - if [ -n "$SRC" ]; then - SADDR=${SRC%%:*}; STEMP=${SRC##*:} - [ "$SADDR" = "$SRC" ] && STEMP="" - - SPORT=${STEMP%%/*}; SMASK=${STEMP##*/} - [ "$SPORT" = "$STEMP" ] && SMASK="0xffff" - fi - - - ### Convert asterisks to empty strings - SADDR=${SADDR#\*}; DADDR=${DADDR#\*} - - ### Compose u32 filter rules - u32_s="${SPORT:+match ip sport $SPORT $SMASK}" - u32_s="${SADDR:+match ip src $SADDR} $u32_s" - u32_d="${DPORT:+match ip dport $DPORT $DMASK}" - u32_d="${DADDR:+match ip dst $DADDR} $u32_d" - - ### Uncomment the following if you want to see parsed rules - #echo "$rule: $u32_s $u32_d" - - ### Attach u32 filter to the appropriate class - tc filter add dev $DEVICE parent 1:0 protocol ip \ - prio $PRIO_RULE u32 $u32_s $u32_d classid 1:$CLASS - done ### rule - - [ "$1" = "compile" ] && echo -done ### classfile -;; - - -############################################################################# -################################# TIME CHECK ################################ -############################################################################# - -timecheck) - -### Get time + weekday -TIME_TMP=`date +%w/%k:%M` -TIME_DOW=${TIME_TMP%%/*} -TIME_NOW=${TIME_TMP##*/} - -### Load DEVICES, DEVFIELDS and CLASSLIST -cbq_init $CBQ_PATH - -### Run through all classes -for classfile in $CLASSLIST; do - ### Gather all TIME rules from class config - TIMESET=`sed -n 's/#.*//; s/[[:space:]]//g; /^TIME/ { s/.*=//; p; }' \ - $CBQ_PATH/$classfile` - [ -z "$TIMESET" ] && continue - - MATCH=0; CHANGE=0 - for timerule in $TIMESET; do - TIME_ABS=`cbq_time2abs $TIME_NOW` - - ### Split TIME rule to pieces - TIMESPEC=${timerule%%;*}; PARAMS=${timerule##*;} - WEEKDAYS=${TIMESPEC%%/*}; INTERVAL=${TIMESPEC##*/} - BEG_TIME=${INTERVAL%%-*}; END_TIME=${INTERVAL##*-} - - ### Check the day-of-week (if present) - [ "$WEEKDAYS" != "$INTERVAL" -a \ - -n "${WEEKDAYS##*$TIME_DOW*}" ] && continue - - ### Compute interval boundaries - BEG_ABS=`cbq_time2abs $BEG_TIME` - END_ABS=`cbq_time2abs $END_TIME` - - ### Midnight wrap fixup - if [ $BEG_ABS -gt $END_ABS ]; then - [ $TIME_ABS -le $END_ABS ] && - TIME_ABS=$[TIME_ABS + 24*60] - - END_ABS=$[END_ABS + 24*60] - fi - - ### If the time matches, remember params and set MATCH flag - if [ $TIME_ABS -ge $BEG_ABS -a $TIME_ABS -lt $END_ABS ]; then - TMP_RATE=${PARAMS%%/*}; PARAMS=${PARAMS#*/} - TMP_WGHT=${PARAMS%%/*}; TMP_PEAK=${PARAMS##*/} - - [ "$TMP_PEAK" = "$TMP_WGHT" ] && TMP_PEAK="" - TMP_PEAK=${TMP_PEAK:+peakrate $TMP_PEAK} - - MATCH=1 - fi - done ### timerule - - - cbq_load_class $CBQ_PATH $classfile - - ### Get current RATE of CBQ class - RATE_NOW=`tc class show dev $DEVICE| sed -n \ - "/cbq 1:$CLASS / { s/.*rate //; s/ .*//; p; q; }"` - [ -z "$RATE_NOW" ] && continue - - ### Time interval matched - if [ $MATCH -ne 0 ]; then - - ### Check if there is any change in class RATE - if [ "$RATE_NOW" != "$TMP_RATE" ]; then - NEW_RATE="$TMP_RATE" - NEW_WGHT="$TMP_WGHT" - NEW_PEAK="$TMP_PEAK" - CHANGE=1 - fi - - ### Match not found, reset to default RATE if necessary - elif [ "$RATE_NOW" != "$RATE" ]; then - NEW_WGHT="$WEIGHT" - NEW_RATE="$RATE" - NEW_PEAK="$PEAK" - CHANGE=1 - fi - - ### If there are no changes, go for next class - [ $CHANGE -eq 0 ] && continue - - ### Replace CBQ class - tc class replace dev $DEVICE classid 1:$CLASS cbq \ - bandwidth $BANDWIDTH rate $NEW_RATE weight $NEW_WGHT prio $PRIO \ - allot 1514 cell 8 maxburst 20 avpkt $AVPKT $BOUNDED $ISOLATED - - ### Replace leaf qdisc (if any) - if [ "$LEAF" = "tbf" ]; then - tc qdisc replace dev $DEVICE handle $CLASS tbf \ - rate $NEW_RATE buffer $BUFFER limit $LIMIT mtu $MTU $NEW_PEAK - fi - - cbq_message "$TIME_NOW: class $CLASS on $DEVICE changed rate ($RATE_NOW -> $NEW_RATE)" -done ### class file -;; - - -############################################################################# -################################## THE REST ################################# -############################################################################# - -stop) - cbq_off - ;; - -list) - cbq_show - ;; - -stats) - cbq_show -s - ;; - -restart) - shift - $0 stop - $0 start "$@" - ;; - -*) - echo "Usage: `basename $0` {start|compile|stop|restart|timecheck|list|stats}" -esac diff --git a/examples/cbqinit.eth1 b/examples/cbqinit.eth1 deleted file mode 100755 index 226ec1c..0000000 --- a/examples/cbqinit.eth1 +++ /dev/null @@ -1,76 +0,0 @@ -#! /bin/sh - -TC=/home/root/tc -IP=/home/root/ip -DEVICE=eth1 -BANDWIDTH="bandwidth 10Mbit" - -# Attach CBQ on $DEVICE. It will have handle 1:. -# $BANDWIDTH is real $DEVICE bandwidth (10Mbit). -# avpkt is average packet size. -# mpu is minimal packet size. - -$TC qdisc add dev $DEVICE root handle 1: cbq \ -$BANDWIDTH avpkt 1000 mpu 64 - -# Create root class with classid 1:1. This step is not necessary. -# bandwidth is the same as on CBQ itself. -# rate == all the bandwidth -# allot is MTU + MAC header -# maxburst measure allowed class burstiness (please,read S.Floyd and VJ papers) -# est 1sec 8sec means, that kernel will evaluate average rate -# on this class with period 1sec and time constant 8sec. -# This rate is viewed with "tc -s class ls dev $DEVICE" - -$TC class add dev $DEVICE parent 1:0 classid :1 est 1sec 8sec cbq \ -$BANDWIDTH rate 10Mbit allot 1514 maxburst 50 avpkt 1000 - -# Bulk. -# New parameters are: -# weight, which is set to be proportional to -# "rate". It is not necessary, weight=1 will work as well. -# defmap and split say that best effort ttraffic, not classfied -# by another means will fall to this class. - -$TC class add dev $DEVICE parent 1:1 classid :2 est 1sec 8sec cbq \ -$BANDWIDTH rate 4Mbit allot 1514 weight 500Kbit \ -prio 6 maxburst 50 avpkt 1000 split 1:0 defmap ff3d - -# OPTIONAL. -# Attach "sfq" qdisc to this class, quantum is MTU, perturb -# gives period of hash function perturbation in seconds. -# -$TC qdisc add dev $DEVICE parent 1:2 sfq quantum 1514b perturb 15 - -# Interactive-burst class - -$TC class add dev $DEVICE parent 1:1 classid :3 est 2sec 16sec cbq \ -$BANDWIDTH rate 1Mbit allot 1514 weight 100Kbit \ -prio 2 maxburst 100 avpkt 1000 split 1:0 defmap c0 - -$TC qdisc add dev $DEVICE parent 1:3 sfq quantum 1514b perturb 15 - -# Background. - -$TC class add dev $DEVICE parent 1:1 classid :4 est 1sec 8sec cbq \ - $BANDWIDTH rate 100Kbit allot 1514 weight 10Mbit \ - prio 7 maxburst 10 avpkt 1000 split 1:0 defmap 2 - -$TC qdisc add dev $DEVICE parent 1:4 sfq quantum 1514b perturb 15 - -# Realtime class for RSVP - -$TC class add dev $DEVICE parent 1:1 classid 1:7FFE cbq \ -rate 5Mbit $BANDWIDTH allot 1514b avpkt 1000 \ -maxburst 20 - -# Reclassified realtime traffic -# -# New element: split is not 1:0, but 1:7FFE. It means, -# that only real-time packets, which violated policing filters -# or exceeded reshaping buffers will fall to it. - -$TC class add dev $DEVICE parent 1:7FFE classid 1:7FFF est 4sec 32sec cbq \ -rate 1Mbit $BANDWIDTH allot 1514b avpkt 1000 weight 10Kbit \ -prio 6 maxburst 10 split 1:7FFE defmap ffff - diff --git a/examples/dhcp-client-script b/examples/dhcp-client-script deleted file mode 100755 index 7207b57..0000000 --- a/examples/dhcp-client-script +++ /dev/null @@ -1,446 +0,0 @@ -#!/bin/bash -# -# dhclient-script for Linux. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -# -# Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> -# -# Probably, I did not understand, what this funny feature as "alias" -# means exactly. For now I suppose, that it is a static address, which -# we should install and preserve. -# - -exec >> /tmp/DHS.log 2>&1 - -echo dhc-script $* reason=$reason -set | grep "^\(old_\|new_\|check_\)" - -LOG () { - echo LOG $* ; -} - -# convert 8bit mask to length -# arg: $1 = mask -# -Mask8ToLen() { - local l=0; - - while [ $l -le 7 ]; do - if [ $[ ( 1 << $l ) + $1 ] -eq 256 ]; then - return $[ 8 - $l ] - fi - l=$[ $l + 1 ] - done - return 0; -} - -# convert inet dotted quad mask to length -# arg: $1 = dotquad mask -# -MaskToLen() { - local masklen=0 - local mask8=$1 - - case $1 in - 0.0.0.0) - return 0; - ;; - 255.*.0.0) - masklen=8 - mask8=${mask8#255.} - mask8=${mask8%.0.0} - ;; - 255.255.*.0) - masklen=16 - mask8=${mask8#255.255.} - mask8=${mask8%.0} - ;; - 255.255.255.*) - masklen=24 - mask8=${mask8#255.255.255.} - ;; - *) - return 255 - ;; - esac - Mask8ToLen $mask8 - return $[ $? + $masklen ] -} - -# calculate ABC "natural" mask -# arg: $1 = dotquad address -# -ABCMask () { - local class; - - class=${1%%.*} - - if [ "$1" = "255.255.255.255" ]; then - echo $1 - elif [ "$1" = "0.0.0.0" ]; then - echo $1 - elif [ $class -ge 224 ]; then - echo 240.0.0.0 - elif [ $class -ge 192 ]; then - echo 255.255.255.0 - elif [ $class -ge 128 ]; then - echo 255.255.0.0 - else - echo 255.0.0.0 - fi -} - -# calculate ABC "natural" mask length -# arg: $1 = dotquad address -# -ABCMaskLen () { - local class; - - class=${1%%.*} - - if [ "$1" = "255.255.255.255" ]; then - return 32 - elif [ "$1" = "0.0.0.0" ]; then - return 0 - elif [ $class -ge 224 ]; then - return 4; - elif [ $class -ge 192 ]; then - return 24; - elif [ $class -ge 128 ]; then - return 16; - else - return 8; - fi -} - -# Delete IP address -# args: $1 = interface -# $2 = address -# $3 = mask -# $4 = broadcast -# $5 = label -# -DelINETAddr () { - local masklen=32 - local addrid=$1 - - LOG DelINETAddr $* - - if [ "$5" ]; then - addrid=$addrid:$5 - fi - LOG ifconfig $addrid down - ifconfig $addrid down -} - -# Add IP address -# args: $1 = interface -# $2 = address -# $3 = mask -# $4 = broadcast -# $5 = label -# -AddINETAddr () { - local mask_arg - local brd_arg - local addrid=$1 - - LOG AddINETAddr $* - - if [ "$5" ]; then - addrid=$addrid:$5 - fi - if [ "$3" ]; then - mask_arg="netmask $3" - fi - if [ "$4" ]; then - brd_arg="broadcast $4" - fi - - LOG ifconfig $addrid $2 $mask_arg $brd_arg up - ifconfig $addrid $2 $mask_arg $brd_arg up -} - -# Add default routes -# args: $1 = routers list -# -AddDefaultRoutes() { - local router - - if [ "$1" ]; then - LOG AddDefaultRoutes $* - for router in $1; do - LOG route add default gw $router - route add default gw $router - done ; - fi -} - -# Delete default routes -# args: $1 = routers list -# -DelDefaultRoutes() { - local router - - if [ "$1" ]; then - LOG DelDefaultRoutes $* - - for router in $1; do - LOG route del default gw $router - route del default gw $router - done - fi -} - -# ping a host -# args: $1 = dotquad address of the host -# -PingNode() { - LOG PingNode $* - if ping -q -c 1 -w 2 $1 ; then - return 0; - fi - return 1; -} - -# Check (and add route, if alive) default routers -# args: $1 = routers list -# returns: 0 if at least one router is alive. -# -CheckRouterList() { - local router - local succeed=1 - - LOG CheckRouterList $* - - for router in $1; do - if PingNode $router ; then - succeed=0 - route add default gw $router - fi - done - return $succeed -} - -# Delete/create static routes. -# args: $1 = operation (del/add) -# $2 = routes list in format "dst1 nexthop1 dst2 ..." -# -# BEWARE: this feature of DHCP is obsolete, because does not -# support subnetting. -# -X-StaticRouteList() { - local op=$1 - local lst="$2" - local masklen - - LOG X-StaticRouteList $* - - if [ "$lst" ]; then - set $lst - while [ $# -gt 1 ]; do - route $op -net $1 netmask `ABCMask "$1"` gw $2 - shift; shift; - done - fi -} - -# Create static routes. -# arg: $1 = routes list in format "dst1 nexthop1 dst2 ..." -# -AddStaticRouteList() { - LOG AddStaticRouteList $* - X-StaticRouteList add "$1" -} - -# Delete static routes. -# arg: $1 = routes list in format "dst1 nexthop1 dst2 ..." -# -DelStaticRouteList() { - LOG DelStaticRouteList $* - X-StaticRouteList del "$1" -} - -# Broadcast unsolicited ARP to update neighbours' caches. -# args: $1 = interface -# $2 = address -# -UnsolicitedARP() { - if [ -f /sbin/arping ]; then - /sbin/arping -A -c 1 -I "$1" "$2" & - (sleep 2 ; /sbin/arping -U -c 1 -I "$1" "$2" ) & - fi -} - -# Duplicate address detection. -# args: $1 = interface -# $2 = test address -# returns: 0, if DAD succeeded. -DAD() { - if [ -f /sbin/arping ]; then - /sbin/arping -c 2 -w 3 -D -I "$1" "$2" - return $? - fi - return 0 -} - - -# Setup resolver. -# args: NO -# domain and nameserver list are passed in global variables. -# -# NOTE: we try to be careful and not to break user supplied resolv.conf. -# The script mangles it, only if it has dhcp magic signature. -# -UpdateDNS() { - local nameserver - local idstring="#### Generated by DHCPCD" - - LOG UpdateDNS $* - - if [ "$new_domain_name" = "" -a "$new_domain_name_servers" = "" ]; then - return 0; - fi - - echo $idstring > /etc/resolv.conf.dhcp - if [ "$new_domain_name" ]; then - echo search $new_domain_name >> /etc/resolv.conf.dhcp - fi - echo options ndots:1 >> /etc/resolv.conf.dhcp - - if [ "$new_domain_name_servers" ]; then - for nameserver in $new_domain_name_servers; do - echo nameserver $nameserver >> /etc/resolv.conf.dhcp - done - else - echo nameserver 127.0.0.1 >> /etc/resolv.conf.dhcp - fi - - if [ -f /etc/resolv.conf ]; then - if [ "`head -1 /etc/resolv.conf`" != "$idstring" ]; then - return 0 - fi - if [ "$old_domain_name" = "$new_domain_name" -a - "$new_domain_name_servers" = "$old_domain_name_servers" ]; then - return 0 - fi - fi - mv /etc/resolv.conf.dhcp /etc/resolv.conf -} - -case $reason in -NBI) - exit 1 - ;; - -MEDIUM) - exit 0 - ;; - -PREINIT) - ifconfig $interface:dhcp down - ifconfig $interface:dhcp1 down - if [ -d /proc/sys/net/ipv4/conf/$interface ]; then - ifconfig $interface:dhcp 10.10.10.10 netmask 255.255.255.255 - ifconfig $interface:dhcp down - if [ -d /proc/sys/net/ipv4/conf/$interface ]; then - LOG The interface $interface already configured. - fi - fi - ifconfig $interface:dhcp up - exit 0 - ;; - -ARPSEND) - exit 0 - ;; - -ARPCHECK) - if DAD "$interface" "$check_ip_address" ; then - exit 0 - fi - exit 1 - ;; - -BOUND|RENEW|REBIND|REBOOT) - if [ "$old_ip_address" -a "$alias_ip_address" -a \ - "$alias_ip_address" != "$old_ip_address" ]; then - DelINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1 - fi - if [ "$old_ip_address" -a "$old_ip_address" != "$new_ip_address" ]; then - DelINETAddr "$interface" "$old_ip_address" "$old_subnet_mask" "$old_broadcast_address" dhcp - DelDefaultRoutes "$old_routers" - DelStaticRouteList "$old_static_routes" - fi - if [ "$old_ip_address" = "" -o "$old_ip_address" != "$new_ip_address" -o \ - "$reason" = "BOUND" -o "$reason" = "REBOOT" ]; then - AddINETAddr "$interface" "$new_ip_address" "$new_subnet_mask" "$new_broadcast_address" dhcp - AddStaticRouteList "$new_static_routes" - AddDefaultRoutes "$new_routers" - UnsolicitedARP "$interface" "$new_ip_address" - fi - if [ "$new_ip_address" != "$alias_ip_address" -a "$alias_ip_address" ]; then - AddINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1 - fi - UpdateDNS - exit 0 - ;; - -EXPIRE|FAIL) - if [ "$alias_ip_address" ]; then - DelINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1 - fi - if [ "$old_ip_address" ]; then - DelINETAddr "$interface" "$old_ip_address" "$old_subnet_mask" "$old_broadcast_address" dhcp - DelDefaultRoutes "$old_routers" - DelStaticRouteList "$old_static_routes" - fi - if [ "$alias_ip_address" ]; then - AddINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1 - fi - exit 0 - ;; - -TIMEOUT) - if [ "$alias_ip_address" ]; then - DelINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1 - fi -# Seems, <null address> means, that no more old leases found. -# Or does it mean bug in dhcpcd? 8) Fail for now. - if [ "$new_ip_address" = "<null address>" ]; then - if [ "$old_ip_address" ]; then - DelINETAddr "$interface" "$old_ip_address" "$old_subnet_mask" "$old_broadcast_address" dhcp - fi - if [ "$alias_ip_address" ]; then - AddINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1 - fi - exit 1 - fi - if DAD "$interface" "$new_ip_address" ; then - AddINETAddr "$interface" "$new_ip_address" "$new_subnet_mask" "$new_broadcast_address" dhcp - UnsolicitedARP "$interface" "$new_ip_address" - if [ "$alias_ip_address" -a "$alias_ip_address" != "$new_ip_address" ]; then - AddINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1 - UnsolicitedARP "$interface" "$alias_ip_address" - fi - if CheckRouterList "$new_routers" ; then - AddStaticRouteList "$new_static_routes" - UpdateDNS - exit 0 - fi - fi - DelINETAddr "$interface" "$new_ip_address" "$new_subnet_mask" "$new_broadcast_address" dhcp - DelDefaultRoutes "$old_routers" - DelStaticRouteList "$old_static_routes" - if [ "$alias_ip_address" ]; then - AddINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1 - fi - exit 1 - ;; -esac - -exit 0 diff --git a/examples/diffserv/Edge1 b/examples/diffserv/Edge1 deleted file mode 100644 index 4ddffdd..0000000 --- a/examples/diffserv/Edge1 +++ /dev/null @@ -1,68 +0,0 @@ -#! /bin/sh -x -# -# sample script on using the ingress capabilities -# This script just tags on the ingress interfac using Ipchains -# the result is used for fast classification and re-marking -# on the egress interface -# -#path to various utilities; -#change to reflect yours. -# -IPROUTE=/root/DS-6-beta/iproute2-990530-dsing -TC=$IPROUTE/tc/tc -IP=$IPROUTE/ip/ip -IPCHAINS=/root/DS-6-beta/ipchains-1.3.9/ipchains -INDEV=eth2 -EGDEV="dev eth1" -# -# tag all incoming packets from host 10.2.0.24 to value 1 -# tag all incoming packets from host 10.2.0.3 to value 2 -# tag the rest of incoming packets from subnet 10.2.0.0/24 to value 3 -#These values are used in the egress -# -############################################################ -$IPCHAINS -A input -s 10.2.0.4/24 -m 3 -$IPCHAINS -A input -i $INDEV -s 10.2.0.24 -m 1 -$IPCHAINS -A input -i $INDEV -s 10.2.0.3 -m 2 - -######################## Egress side ######################## - - -# attach a dsmarker -# -$TC qdisc add $EGDEV handle 1:0 root dsmark indices 64 set_tc_index -# -# values of the DSCP to change depending on the class -# -#becomes EF -$TC class change $EGDEV classid 1:1 dsmark mask 0x3 \ - value 0xb8 -#becomes AF11 -$TC class change $EGDEV classid 1:2 dsmark mask 0x3 \ - value 0x28 -#becomes AF21 -$TC class change $EGDEV classid 1:3 dsmark mask 0x3 \ - value 0x48 -# -# -# The class mapping -# -$TC filter add $EGDEV parent 1:0 protocol ip prio 4 handle 1 fw classid 1:1 -$TC filter add $EGDEV parent 1:0 protocol ip prio 4 handle 2 fw classid 1:2 -$TC filter add $EGDEV parent 1:0 protocol ip prio 4 handle 3 fw classid 1:3 -# - -# -echo "---- qdisc parameters Ingress ----------" -$TC qdisc ls dev $INDEV -echo "---- Class parameters Ingress ----------" -$TC class ls dev $INDEV -echo "---- filter parameters Ingress ----------" -$TC filter ls dev $INDEV parent 1:0 - -echo "---- qdisc parameters Egress ----------" -$TC qdisc ls $EGDEV -echo "---- Class parameters Egress ----------" -$TC class ls $EGDEV -echo "---- filter parameters Egress ----------" -$TC filter ls $EGDEV parent 1:0 diff --git a/examples/diffserv/Edge2 b/examples/diffserv/Edge2 deleted file mode 100644 index 2f78da2..0000000 --- a/examples/diffserv/Edge2 +++ /dev/null @@ -1,87 +0,0 @@ -#! /bin/sh -x -# -# sample script on using the ingress capabilities -# This script tags the fwmark on the ingress interface using IPchains -# the result is used first for policing on the Ingress interface then -# for fast classification and re-marking -# on the egress interface -# -#path to various utilities; -#change to reflect yours. -# -IPROUTE=/root/DS-6-beta/iproute2-990530-dsing -TC=$IPROUTE/tc/tc -IP=$IPROUTE/ip/ip -IPCHAINS=/root/DS-6-beta/ipchains-1.3.9/ipchains -INDEV=eth2 -EGDEV="dev eth1" -# -# tag all incoming packets from host 10.2.0.24 to value 1 -# tag all incoming packets from host 10.2.0.3 to value 2 -# tag the rest of incoming packets from subnet 10.2.0.0/24 to value 3 -#These values are used in the egress -############################################################ -$IPCHAINS -A input -s 10.2.0.0/24 -m 3 -$IPCHAINS -A input -i $INDEV -s 10.2.0.24 -m 1 -$IPCHAINS -A input -i $INDEV -s 10.2.0.3 -m 2 -############################################################ -# -# install the ingress qdisc on the ingress interface -############################################################ -$TC qdisc add dev $INDEV handle ffff: ingress -############################################################ - -# -# attach a fw classifier to the ingress which polices anything marked -# by ipchains to tag value 3 (The rest of the subnet packets -- not -# tag 1 or 2) to not go beyond 1.5Mbps -# Allow up to at least 60 packets to burst (assuming maximum packet -# size of # 1.5 KB) in the long run and upto about 6 packets in the -# shot run - -############################################################ -$TC filter add dev $INDEV parent ffff: protocol ip prio 50 handle 3 fw \ -police rate 1500kbit burst 90k mtu 9k drop flowid :1 -############################################################ - -######################## Egress side ######################## - - -# attach a dsmarker -# -$TC qdisc add $EGDEV handle 1:0 root dsmark indices 64 -# -# values of the DSCP to change depending on the class -# -$TC class change $EGDEV classid 1:1 dsmark mask 0x3 \ - value 0xb8 -$TC class change $EGDEV classid 1:2 dsmark mask 0x3 \ - value 0x28 -$TC class change $EGDEV classid 1:3 dsmark mask 0x3 \ - value 0x48 -# -# -# The class mapping -# -$TC filter add $EGDEV parent 1:0 protocol ip prio 4 handle 1 fw classid 1:1 -$TC filter add $EGDEV parent 1:0 protocol ip prio 4 handle 2 fw classid 1:2 -$TC filter add $EGDEV parent 1:0 protocol ip prio 4 handle 3 fw classid 1:3 -# - -# -echo "---- qdisc parameters Ingress ----------" -$TC qdisc ls dev $INDEV -echo "---- Class parameters Ingress ----------" -$TC class ls dev $INDEV -echo "---- filter parameters Ingress ----------" -$TC filter ls dev $INDEV parent ffff: - -echo "---- qdisc parameters Egress ----------" -$TC qdisc ls $EGDEV -echo "---- Class parameters Egress ----------" -$TC class ls $EGDEV -echo "---- filter parameters Egress ----------" -$TC filter ls $EGDEV parent 1:0 -# -#deleting the ingress qdisc -#$TC qdisc del $DEV ingress diff --git a/examples/diffserv/Edge31-ca-u32 b/examples/diffserv/Edge31-ca-u32 deleted file mode 100644 index 25e6c0b..0000000 --- a/examples/diffserv/Edge31-ca-u32 +++ /dev/null @@ -1,170 +0,0 @@ -#! /bin/sh -x -# -# sample script on using the ingress capabilities using u32 classifier -# This script tags tcindex based on metering on the ingress -# interface the result is used for fast classification and re-marking -# on the egress interface -# This is an example of a color aware mode marker with PIR configured -# based on draft-wahjak-mcm-00.txt (section 3.1) -# -# The colors are defined using the Diffserv Fields -#path to various utilities; -#change to reflect yours. -# -IPROUTE=/usr/src/iproute2-current -TC=$IPROUTE/tc/tc -IP=$IPROUTE/ip/ip -INDEV=eth0 -EGDEV="dev eth1" -CIR1=1500kbit -CIR2=1000kbit - -#The CBS is about 60 MTU sized packets -CBS1=90k -CBS2=90k - -############################################################ -# -# install the ingress qdisc on the ingress interface -$TC qdisc add dev $INDEV handle ffff: ingress -############################################################ -# -# Create u32 filters -$TC filter add dev $INDEV parent ffff: protocol ip prio 4 handle 1: u32 \ -divisor 1 -############################################################ - -# The meters: Note that we have shared meters in this case as identified -# by the index parameter -meter1=" police index 1 rate $CIR1 burst $CBS1 " -meter2=" police index 2 rate $CIR2 burst $CBS1 " -meter3=" police index 3 rate $CIR2 burst $CBS2 " -meter4=" police index 4 rate $CIR1 burst $CBS2 " -meter5=" police index 5 rate $CIR1 burst $CBS2 " - -# All packets are marked with a tcindex value which is used on the egress -# tcindex 1 maps to AF41, 2->AF42, 3->AF43, 4->BE - -# *********************** AF41 *************************** -#AF41 (DSCP 0x22) is passed on with a tcindex value 1 -#if it doesnt exceed its CIR/CBS -#policer 1 is used. -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 4 u32 \ -match ip tos 0x88 0xfc \ -$meter1 \ -continue flowid :1 -# -# if it exceeds the above but not the extra rate/burst below, it gets a -# tcindex value of 2 -# policer 2 is used -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 5 u32 \ -match ip tos 0x88 0xfc \ -$meter2 \ -continue flowid :2 -# -# if it exceeds the above but not the rule below, it gets a tcindex value -# of 3 (policer 3) -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 6 u32 \ -match ip tos 0x88 0xfc \ -$meter3 \ -drop flowid :3 -# - -# *********************** AF42 *************************** -#AF42 (DSCP 0x24) from is passed on with a tcindex value 2 -#if it doesnt exceed its CIR/CBS -#policer 2 is used. Note that this is shared with the AF41 -# -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 5 u32 \ -match ip tos 0x90 0xfc \ -$meter2 \ -continue flowid :2 -# -# if it exceeds the above but not the rule below, it gets a tcindex value -# of 3 (policer 3) -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 6 u32 \ -match ip tos 0x90 0xfc \ -$meter3 \ -drop flowid :3 -# -# *********************** AF43 *************************** -# -#AF43 (DSCP 0x26) from is passed on with a tcindex value 3 -#if it doesnt exceed its CIR/CBS -#policer 3 is used. Note that this is shared with the AF41 and AF42 -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 6 u32 \ -match ip tos 0x98 0xfc \ -$meter3 \ -drop flowid :3 -# -# *********************** BE *************************** -# -# Anything else (not from the AF4*) gets discarded if it -# exceeds 1Mbps and by default goes to BE if it doesnt -# Note that the BE class is also used by the AF4* in the worst -# case -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 7 u32 \ -match ip src 0/0\ -$meter4 \ -drop flowid :4 - -######################## Egress side ######################## - -# attach a dsmarker -# -$TC qdisc add $EGDEV handle 1:0 root dsmark indices 64 -# -# values of the DSCP to change depending on the class -#note that the ECN bits are masked out -# -#AF41 (0x88 is 0x22 shifted to the right by two bits) -# -$TC class change $EGDEV classid 1:1 dsmark mask 0x3 \ - value 0x88 -#AF42 -$TC class change $EGDEV classid 1:2 dsmark mask 0x3 \ - value 0x90 -#AF43 -$TC class change $EGDEV classid 1:3 dsmark mask 0x3 \ - value 0x98 -#BE -$TC class change $EGDEV classid 1:3 dsmark mask 0x3 \ - value 0x0 -# -# -# The class mapping -# -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 1 tcindex classid 1:1 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 2 tcindex classid 1:2 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 3 tcindex classid 1:3 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 4 tcindex classid 1:4 -# - -# -echo "---- qdisc parameters Ingress ----------" -$TC qdisc ls dev $INDEV -echo "---- Class parameters Ingress ----------" -$TC class ls dev $INDEV -echo "---- filter parameters Ingress ----------" -$TC filter ls dev $INDEV parent ffff: - -echo "---- qdisc parameters Egress ----------" -$TC qdisc ls $EGDEV -echo "---- Class parameters Egress ----------" -$TC class ls $EGDEV -echo "---- filter parameters Egress ----------" -$TC filter ls $EGDEV parent 1:0 -# -#deleting the ingress qdisc -#$TC qdisc del $INDEV ingress diff --git a/examples/diffserv/Edge31-cb-chains b/examples/diffserv/Edge31-cb-chains deleted file mode 100644 index d7faae9..0000000 --- a/examples/diffserv/Edge31-cb-chains +++ /dev/null @@ -1,132 +0,0 @@ -#! /bin/sh -x -# -# sample script on using the ingress capabilities -# This script fwmark tags(IPchains) based on metering on the ingress -# interface the result is used for fast classification and re-marking -# on the egress interface -# This is an example of a color blind mode marker with no PIR configured -# based on draft-wahjak-mcm-00.txt (section 3.1) -# -#path to various utilities; -#change to reflect yours. -# -IPROUTE=/root/DS-6-beta/iproute2-990530-dsing -TC=$IPROUTE/tc/tc -IP=$IPROUTE/ip/ip -IPCHAINS=/root/DS-6-beta/ipchains-1.3.9/ipchains -INDEV=eth2 -EGDEV="dev eth1" -CIR1=1500kbit -CIR2=1000kbit - -#The CBS is about 60 MTU sized packets -CBS1=90k -CBS2=90k - -meter1="police rate $CIR1 burst $CBS1 " -meter2="police rate $CIR1 burst $CBS2 " -meter3="police rate $CIR2 burst $CBS1 " -meter4="police rate $CIR2 burst $CBS2 " -meter5="police rate $CIR2 burst $CBS2 " -# -# tag the rest of incoming packets from subnet 10.2.0.0/24 to fw value 1 -# tag all incoming packets from any other subnet to fw tag 2 -############################################################ -$IPCHAINS -A input -i $INDEV -s 0/0 -m 2 -$IPCHAINS -A input -i $INDEV -s 10.2.0.0/24 -m 1 -# -############################################################ -# install the ingress qdisc on the ingress interface -$TC qdisc add dev $INDEV handle ffff: ingress -# -############################################################ - -# All packets are marked with a tcindex value which is used on the egress -# tcindex 1 maps to AF41, 2->AF42, 3->AF43, 4->BE -# -############################################################ -# -# anything with fw tag of 1 is passed on with a tcindex value 1 -#if it doesnt exceed its allocated rate (CIR/CBS) -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 4 handle 1 fw \ -$meter1 \ -continue flowid 4:1 -# -# if it exceeds the above but not the extra rate/burst below, it gets a -#tcindex value of 2 -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 5 handle 1 fw \ -$meter2 \ -continue flowid 4:2 -# -# if it exceeds the above but not the rule below, it gets a tcindex value -# of 3 -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 6 handle 1 fw \ -$meter3 \ -drop flowid 4:3 -# -# Anything else (not from the subnet 10.2.0.24/24) gets discarded if it -# exceeds 1Mbps and by default goes to BE if it doesnt -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 6 handle 2 fw \ -$meter5 \ -drop flowid 4:4 - - -######################## Egress side ######################## - - -# attach a dsmarker -# -$TC qdisc add $EGDEV handle 1:0 root dsmark indices 64 -# -# values of the DSCP to change depending on the class -#note that the ECN bits are masked out -# -#AF41 (0x88 is 0x22 shifted to the right by two bits) -# -$TC class change $EGDEV classid 1:1 dsmark mask 0x3 \ - value 0x88 -#AF42 -$TC class change $EGDEV classid 1:2 dsmark mask 0x3 \ - value 0x90 -#AF43 -$TC class change $EGDEV classid 1:3 dsmark mask 0x3 \ - value 0x98 -#BE -$TC class change $EGDEV classid 1:4 dsmark mask 0x3 \ - value 0x0 -# -# -# The class mapping (using tcindex; could easily have -# replaced it with the fw classifier instead) -# -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 1 tcindex classid 1:1 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 2 tcindex classid 1:2 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 3 tcindex classid 1:3 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 4 tcindex classid 1:4 -# - -# -echo "---- qdisc parameters Ingress ----------" -$TC qdisc ls dev $INDEV -echo "---- Class parameters Ingress ----------" -$TC class ls dev $INDEV -echo "---- filter parameters Ingress ----------" -$TC filter ls dev $INDEV parent ffff: - -echo "---- qdisc parameters Egress ----------" -$TC qdisc ls $EGDEV -echo "---- Class parameters Egress ----------" -$TC class ls $EGDEV -echo "---- filter parameters Egress ----------" -$TC filter ls $EGDEV parent 1:0 -# -#deleting the ingress qdisc -#$TC qdisc del $INDEV ingress diff --git a/examples/diffserv/Edge32-ca-u32 b/examples/diffserv/Edge32-ca-u32 deleted file mode 100644 index edf21e4..0000000 --- a/examples/diffserv/Edge32-ca-u32 +++ /dev/null @@ -1,198 +0,0 @@ -#! /bin/sh -x -# -# sample script on using the ingress capabilities using u32 classifier -# This script tags tcindex based on metering on the ingress -# interface the result is used for fast classification and re-marking -# on the egress interface -# This is an example of a color aware mode marker with PIR configured -# based on draft-wahjak-mcm-00.txt (section 3.2) -# -# The colors are defined using the Diffserv Fields -#path to various utilities; -#change to reflect yours. -# -IPROUTE=/root/DS-6-beta/iproute2-990530-dsing -TC=$IPROUTE/tc/tc -IP=$IPROUTE/ip/ip -IPCHAINS=/root/DS-6-beta/ipchains-1.3.9/ipchains -INDEV=eth2 -EGDEV="dev eth1" -CIR1=1000kbit -CIR2=500kbit -# the PIR is what is in excess of the CIR -PIR1=1000kbit -PIR2=500kbit - -#The CBS is about 60 MTU sized packets -CBS1=90k -CBS2=90k -#the EBS is about 20 max sized packets -EBS1=30k -EBS2=30k - -# The meters: Note that we have shared meters in this case as identified -# by the index parameter -meter1=" police index 1 rate $CIR1 burst $CBS1 " -meter1a=" police index 2 rate $PIR1 burst $EBS1 " -meter2=" police index 3 rate $CIR2 burst $CBS1 " -meter2a=" police index 4 rate $PIR2 burst $EBS1 " -meter3=" police index 5 rate $CIR2 burst $CBS2 " -meter3a=" police index 6 rate $PIR2 burst $EBS2 " -meter4=" police index 7 rate $CIR1 burst $CBS2 " - -############################################################ -# -# install the ingress qdisc on the ingress interface -$TC qdisc add dev $INDEV handle ffff: ingress -############################################################ -# -# All packets are marked with a tcindex value which is used on the egress -# tcindex 1 maps to AF41, 2->AF42, 3->AF43, 4->BE -# -# *********************** AF41 *************************** -#AF41 (DSCP 0x22) from is passed on with a tcindex value 1 -#if it doesnt exceed its CIR/CBS + PIR/EBS -#policer 1 is used. -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 1 u32 \ -match ip tos 0x88 0xfc \ -$meter1 \ -continue flowid :1 -$TC filter add dev $INDEV parent ffff: protocol ip prio 2 u32 \ -match ip tos 0x88 0xfc \ -$meter1a \ -continue flowid :1 -# -# if it exceeds the above but not the extra rate/burst below, it gets a -# tcindex value of 2 -# policer 2 is used -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 3 u32 \ -match ip tos 0x88 0xfc \ -$meter2 \ -continue flowid :2 -$TC filter add dev $INDEV parent ffff: protocol ip prio 4 u32 \ -match ip tos 0x88 0xfc \ -$meter2a \ -continue flowid :2 -# -# if it exceeds the above but not the rule below, it gets a tcindex value -# of 3 (policer 3) -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 5 u32 \ -match ip tos 0x88 0xfc \ -$meter3 \ -continue flowid :3 -$TC filter add dev $INDEV parent ffff: protocol ip prio 6 u32 \ -match ip tos 0x88 0xfc \ -$meter3a \ -drop flowid :3 -# -# *********************** AF42 *************************** -#AF42 (DSCP 0x24) from is passed on with a tcindex value 2 -#if it doesnt exceed its CIR/CBS + PIR/EBS -#policer 2 is used. Note that this is shared with the AF41 -# -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 8 u32 \ -match ip tos 0x90 0xfc \ -$meter2 \ -continue flowid :2 -$TC filter add dev $INDEV parent ffff: protocol ip prio 9 u32 \ -match ip tos 0x90 0xfc \ -$meter2a \ -continue flowid :2 -# -# if it exceeds the above but not the rule below, it gets a tcindex value -# of 3 (policer 3) -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 10 u32 \ -match ip tos 0x90 0xfc \ -$meter3 \ -continue flowid :3 -$TC filter add dev $INDEV parent ffff: protocol ip prio 11 u32 \ -match ip tos 0x90 0xfc \ -$meter3a \ -drop flowid :3 - -# -# *********************** AF43 *************************** -# -#AF43 (DSCP 0x26) from is passed on with a tcindex value 3 -#if it doesnt exceed its CIR/CBS + PIR/EBS -#policer 3 is used. Note that this is shared with the AF41 and AF42 -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 13 u32 \ -match ip tos 0x98 0xfc \ -$meter3 \ -continue flowid :3 -$TC filter add dev $INDEV parent ffff: protocol ip prio 14 u32 \ -match ip tos 0x98 0xfc \ -$meter3a \ -drop flowid :3 -# -## *********************** BE *************************** -## -## Anything else (not from the AF4*) gets discarded if it -## exceeds 1Mbps and by default goes to BE if it doesnt -## Note that the BE class is also used by the AF4* in the worst -## case -## -$TC filter add dev $INDEV parent ffff: protocol ip prio 16 u32 \ -match ip src 0/0\ -$meter4 \ -drop flowid :4 - -######################## Egress side ######################## - -# attach a dsmarker -# -$TC qdisc add $EGDEV handle 1:0 root dsmark indices 64 -# -# values of the DSCP to change depending on the class -#note that the ECN bits are masked out -# -#AF41 (0x88 is 0x22 shifted to the right by two bits) -# -$TC class change $EGDEV classid 1:1 dsmark mask 0x3 \ - value 0x88 -#AF42 -$TC class change $EGDEV classid 1:2 dsmark mask 0x3 \ - value 0x90 -#AF43 -$TC class change $EGDEV classid 1:3 dsmark mask 0x3 \ - value 0x98 -#BE -$TC class change $EGDEV classid 1:3 dsmark mask 0x3 \ - value 0x0 -# -# -# The class mapping -# -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 1 tcindex classid 1:1 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 2 tcindex classid 1:2 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 3 tcindex classid 1:3 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 4 tcindex classid 1:4 -# - -# -echo "---- qdisc parameters Ingress ----------" -$TC qdisc ls dev $INDEV -echo "---- Class parameters Ingress ----------" -$TC class ls dev $INDEV -echo "---- filter parameters Ingress ----------" -$TC filter ls dev $INDEV parent ffff: - -echo "---- qdisc parameters Egress ----------" -$TC qdisc ls $EGDEV -echo "---- Class parameters Egress ----------" -$TC class ls $EGDEV -echo "---- filter parameters Egress ----------" -$TC filter ls $EGDEV parent 1:0 -# -#deleting the ingress qdisc -#$TC qdisc del $INDEV ingress diff --git a/examples/diffserv/Edge32-cb-chains b/examples/diffserv/Edge32-cb-chains deleted file mode 100644 index 804fad1..0000000 --- a/examples/diffserv/Edge32-cb-chains +++ /dev/null @@ -1,144 +0,0 @@ -#! /bin/sh -x -# -# sample script on using the ingress capabilities -# This script fwmark tags(IPchains) based on metering on the ingress -# interface the result is used for fast classification and re-marking -# on the egress interface -# This is an example of a color blind mode marker with no PIR configured -# based on draft-wahjak-mcm-00.txt (section 3.1) -# -#path to various utilities; -#change to reflect yours. -# -IPROUTE=/root/DS-6-beta/iproute2-990530-dsing -TC=$IPROUTE/tc/tc -IP=$IPROUTE/ip/ip -IPCHAINS=/root/DS-6-beta/ipchains-1.3.9/ipchains -INDEV=eth2 -EGDEV="dev eth1" -CIR1=1500kbit -CIR2=500kbit - -#The CBS is about 60 MTU sized packets -CBS1=90k -CBS2=90k - -meter1="police rate $CIR1 burst $CBS1 " -meter1a="police rate $CIR2 burst $CBS1 " -meter2="police rate $CIR1 burst $CBS2 " -meter2a="police rate $CIR2 burst $CBS2 " -meter3="police rate $CIR2 burst $CBS1 " -meter3a="police rate $CIR2 burst $CBS1 " -meter4="police rate $CIR2 burst $CBS2 " -meter5="police rate $CIR1 burst $CBS2 " -# -# tag the rest of incoming packets from subnet 10.2.0.0/24 to fw value 1 -# tag all incoming packets from any other subnet to fw tag 2 -############################################################ -$IPCHAINS -A input -i $INDEV -s 0/0 -m 2 -$IPCHAINS -A input -i $INDEV -s 10.2.0.0/24 -m 1 -# -############################################################ -# install the ingress qdisc on the ingress interface -$TC qdisc add dev $INDEV handle ffff: ingress -# -############################################################ - -# All packets are marked with a tcindex value which is used on the egress -# tcindex 1 maps to AF41, 2->AF42, 3->AF43, 4->BE -# -############################################################ -# -# anything with fw tag of 1 is passed on with a tcindex value 1 -#if it doesnt exceed its allocated rate (CIR/CBS) -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 1 handle 1 fw \ -$meter1 \ -continue flowid 4:1 -$TC filter add dev $INDEV parent ffff: protocol ip prio 2 handle 1 fw \ -$meter1a \ -continue flowid 4:1 -# -# if it exceeds the above but not the extra rate/burst below, it gets a -#tcindex value of 2 -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 3 handle 1 fw \ -$meter2 \ -continue flowid 4:2 -$TC filter add dev $INDEV parent ffff: protocol ip prio 4 handle 1 fw \ -$meter2a \ -continue flowid 4:2 -# -# if it exceeds the above but not the rule below, it gets a tcindex value -# of 3 -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 5 handle 1 fw \ -$meter3 \ -continue flowid 4:3 -$TC filter add dev $INDEV parent ffff: protocol ip prio 6 handle 1 fw \ -$meter3a \ -drop flowid 4:3 -# -# Anything else (not from the subnet 10.2.0.24/24) gets discarded if it -# exceeds 1Mbps and by default goes to BE if it doesnt -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 7 handle 2 fw \ -$meter5 \ -drop flowid 4:4 - - -######################## Egress side ######################## - - -# attach a dsmarker -# -$TC qdisc add $EGDEV handle 1:0 root dsmark indices 64 -# -# values of the DSCP to change depending on the class -#note that the ECN bits are masked out -# -#AF41 (0x88 is 0x22 shifted to the right by two bits) -# -$TC class change $EGDEV classid 1:1 dsmark mask 0x3 \ - value 0x88 -#AF42 -$TC class change $EGDEV classid 1:2 dsmark mask 0x3 \ - value 0x90 -#AF43 -$TC class change $EGDEV classid 1:3 dsmark mask 0x3 \ - value 0x98 -#BE -$TC class change $EGDEV classid 1:4 dsmark mask 0x3 \ - value 0x0 -# -# -# The class mapping (using tcindex; could easily have -# replaced it with the fw classifier instead) -# -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 1 tcindex classid 1:1 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 2 tcindex classid 1:2 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 3 tcindex classid 1:3 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 4 tcindex classid 1:4 -# - -# -echo "---- qdisc parameters Ingress ----------" -$TC qdisc ls dev $INDEV -echo "---- Class parameters Ingress ----------" -$TC class ls dev $INDEV -echo "---- filter parameters Ingress ----------" -$TC filter ls dev $INDEV parent ffff: - -echo "---- qdisc parameters Egress ----------" -$TC qdisc ls $EGDEV -echo "---- Class parameters Egress ----------" -$TC class ls $EGDEV -echo "---- filter parameters Egress ----------" -$TC filter ls $EGDEV parent 1:0 -# -#deleting the ingress qdisc -#$TC qdisc del $INDEV ingress diff --git a/examples/diffserv/Edge32-cb-u32 b/examples/diffserv/Edge32-cb-u32 deleted file mode 100644 index cc2ebb4..0000000 --- a/examples/diffserv/Edge32-cb-u32 +++ /dev/null @@ -1,145 +0,0 @@ -#! /bin/sh -# -# sample script on using the ingress capabilities using u32 classifier -# This script tags tcindex based on metering on the ingress -# interface the result is used for fast classification and re-marking -# on the egress interface -# This is an example of a color blind mode marker with PIR configured -# based on draft-wahjak-mcm-00.txt (section 3.2) -# -#path to various utilities; -#change to reflect yours. -# -IPROUTE=/root/DS-6-beta/iproute2-990530-dsing -TC=$IPROUTE/tc/tc -IP=$IPROUTE/ip/ip -INDEV=eth2 -EGDEV="dev eth1" -CIR1=1000kbit -CIR2=1000kbit -# The PIR is the excess (in addition to the CIR i.e if always -# going to the PIR --> average rate is CIR+PIR) -PIR1=1000kbit -PIR2=500kbit - -#The CBS is about 60 MTU sized packets -CBS1=90k -CBS2=90k -#the EBS is about 10 max sized packets -EBS1=15k -EBS2=15k -# The meters -meter1=" police rate $CIR1 burst $CBS1 " -meter1a=" police rate $PIR1 burst $EBS1 " -meter2=" police rate $CIR2 burst $CBS1 " -meter2a="police rate $PIR2 burst $CBS1 " -meter3=" police rate $CIR2 burst $CBS2 " -meter3a=" police rate $PIR2 burst $EBS2 " -meter4=" police rate $CIR1 burst $CBS2 " -meter5=" police rate $CIR1 burst $CBS2 " - - -# install the ingress qdisc on the ingress interface -############################################################ -$TC qdisc add dev $INDEV handle ffff: ingress -############################################################ -# -############################################################ - -# All packets are marked with a tcindex value which is used on the egress -# NOTE: tcindex 1 maps to AF41, 2->AF42, 3->AF43, 4->BE -# -#anything from subnet 10.2.0.2/24 is passed on with a tcindex value 1 -#if it doesnt exceed its CIR/CBS + PIR/EBS -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 1 u32 \ -match ip src 10.2.0.0/24 $meter1 \ -continue flowid :1 -$TC filter add dev $INDEV parent ffff: protocol ip prio 2 u32 \ -match ip src 10.2.0.0/24 $meter1a \ -continue flowid :1 - -# -# if it exceeds the above but not the extra rate/burst below, it gets a -#tcindex value of 2 -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 3 u32 \ -match ip src 10.2.0.0/24 $meter2 \ -continue flowid :2 -$TC filter add dev $INDEV parent ffff: protocol ip prio 4 u32 \ -match ip src 10.2.0.0/24 $meter2a \ -continue flowid :2 -# -# if it exceeds the above but not the rule below, it gets a tcindex value -# of 3 -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 5 u32 \ -match ip src 10.2.0.0/24 $meter3 \ -continue flowid :3 -$TC filter add dev $INDEV parent ffff: protocol ip prio 6 u32 \ -match ip src 10.2.0.0/24 $meter3a \ -drop flowid :3 -# -# -# Anything else (not from the subnet 10.2.0.24/24) gets discarded if it -# exceeds 1Mbps and by default goes to BE if it doesnt -# -$TC filter add dev $INDEV parent ffff: protocol ip prio 7 u32 \ -match ip src 0/0 $meter5 \ -drop flowid :4 - - -######################## Egress side ######################## - - -# attach a dsmarker -# -$TC qdisc add $EGDEV handle 1:0 root dsmark indices 64 -# -# values of the DSCP to change depending on the class -#note that the ECN bits are masked out -# -#AF41 (0x88 is 0x22 shifted to the right by two bits) -# -$TC class change $EGDEV classid 1:1 dsmark mask 0x3 \ - value 0x88 -#AF42 -$TC class change $EGDEV classid 1:2 dsmark mask 0x3 \ - value 0x90 -#AF43 -$TC class change $EGDEV classid 1:3 dsmark mask 0x3 \ - value 0x98 -#BE -$TC class change $EGDEV classid 1:3 dsmark mask 0x3 \ - value 0x0 -# -# -# The class mapping -# -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 1 tcindex classid 1:1 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 2 tcindex classid 1:2 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 3 tcindex classid 1:3 -$TC filter add $EGDEV parent 1:0 protocol ip prio 1 \ - handle 4 tcindex classid 1:4 -# - -# -echo "---- qdisc parameters Ingress ----------" -$TC qdisc ls dev $INDEV -echo "---- Class parameters Ingress ----------" -$TC class ls dev $INDEV -echo "---- filter parameters Ingress ----------" -$TC filter ls dev $INDEV parent ffff: - -echo "---- qdisc parameters Egress ----------" -$TC qdisc ls $EGDEV -echo "---- Class parameters Egress ----------" -$TC class ls $EGDEV -echo "---- filter parameters Egress ----------" -$TC filter ls $EGDEV parent 1:0 -# -#deleting the ingress qdisc -#$TC qdisc del $INDEV ingress diff --git a/examples/diffserv/README b/examples/diffserv/README deleted file mode 100644 index ec91d63..0000000 --- a/examples/diffserv/README +++ /dev/null @@ -1,98 +0,0 @@ - -Note all these are mere examples which can be customized to your needs - -AFCBQ ------ -AF PHB built using CBQ, DSMARK,GRED (default in GRIO mode) ,RED for BE -and the tcindex classifier with some algorithmic mapping - -EFCBQ ------ -EF PHB built using CBQ (for rate control and prioritization), -DSMARK( to remark DSCPs), tcindex classifier and RED for the BE -traffic. - -EFPRIO ------- -EF PHB using the PRIO scheduler, Token Bucket to rate control EF, -tcindex classifier, DSMARK to remark, and RED for the BE traffic - -EDGE scripts -============== - -CB-3(1|2)-(u32/chains) -====================== - - -The major differences are that the classifier is u32 on -u32 extension -and IPchains on the chains extension. CB stands for color Blind -and 31 is for the mode where only a CIR and CBS are defined whereas -32 stands for a mode where a CIR/CBS + PIR/EBS are defined. - -Color Blind (CB) -==========-----= -We look at one special subnet that we are interested in for simplicty -reasons to demonstrate the capability. We send the packets from that -subnet to AF4*, BE or end up dropping depending on the metering results. - - -The algorithm overview is as follows: - -*classify: - -**case: subnet X ----------------- - if !exceed meter1 tag as AF41 - else - if !exceed meter2 tag as AF42 - else - if !exceed meter 3 tag as AF43 - else - drop - -default case: Any other subnet -------------------------------- - if !exceed meter 5 tag as AF43 - else - drop - - -One Egress side change the DSCPs of the packets to reflect AF4* and BE -based on the tags from the ingress. - -------------------------------------------------------------- - -Color Aware -=========== - -Define some meters with + policing and give them IDs eg - -meter1=police index 1 rate $CIR1 burst $CBS1 -meter2=police index 2 rate $CIR2 burst $CBS2 etc - -General overview: -classify based on the DSCPs and use the policer ids to decide tagging - - -*classify on ingress: - -switch (dscp) { - case AF41: /* tos&0xfc == 0x88 */ - if (!exceed meter1) break; - case AF42: /* tos&0xfc == 0x90 */ - if (!exceed meter2) { - tag as AF42; - break; - } - case AF43: /* tos&0xfc == 0x98 */ - if (!exceed meter3) { - tag as AF43; - break; - } else - drop; - default: - if (!exceed meter4) tag as BE; - else drop; -} - -On the Egress side mark the proper AF tags diff --git a/examples/diffserv/afcbq b/examples/diffserv/afcbq deleted file mode 100644 index 10d6d93..0000000 --- a/examples/diffserv/afcbq +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/perl -# -# -# AF using CBQ for a single interface eth0 -# 4 AF classes using GRED and one BE using RED -# Things you might want to change: -# - the device bandwidth (set at 10Mbits) -# - the bandwidth allocated for each AF class and the BE class -# - the drop probability associated with each AF virtual queue -# -# AF DSCP values used (based on AF draft 04) -# ----------------------------------------- -# AF DSCP values -# AF1 1. 0x0a 2. 0x0c 3. 0x0e -# AF2 1. 0x12 2. 0x14 3. 0x16 -# AF3 1. 0x1a 2. 0x1c 3. 0x1e -# AF4 1. 0x22 2. 0x24 3. 0x26 - -# -# -# A simple DSCP-class relationship formula used to generate -# values in the for loop of this script; $drop stands for the -# DP -# $dscp = ($class*8+$drop*2) -# -# if you use GRIO buffer sharing, then GRED priority is set as follows: -# $gprio=$drop+1; -# - -$TC = "/usr/src/iproute2-current/tc/tc"; -$DEV = "dev lo"; -$DEV = "dev eth1"; -$DEV = "dev eth0"; -# the BE-class number -$beclass = "5"; - -#GRIO buffer sharing on or off? -$GRIO = ""; -$GRIO = "grio"; -# The bandwidth of your device -$linerate="10Mbit"; -# The BE and AF rates -%rate_table=(); -$berate="1500Kbit"; -$rate_table{"AF1rate"}="1500Kbit"; -$rate_table{"AF2rate"}="1500Kbit"; -$rate_table{"AF3rate"}="1500Kbit"; -$rate_table{"AF4rate"}="1500Kbit"; -# -# -# -print "\n# --- General setup ---\n"; -print "$TC qdisc add $DEV handle 1:0 root dsmark indices 64 set_tc_index\n"; -print "$TC filter add $DEV parent 1:0 protocol ip prio 1 tcindex mask 0xfc " . - "shift 2 pass_on\n"; - #"shift 2\n"; -print "$TC qdisc add $DEV parent 1:0 handle 2:0 cbq bandwidth $linerate ". - "cell 8 avpkt 1000 mpu 64\n"; -print "$TC filter add $DEV parent 2:0 protocol ip prio 1 tcindex ". - "mask 0xf0 shift 4 pass_on\n"; -for $class (1..4) { - print "\n# --- AF Class $class specific setup---\n"; - $AFrate=sprintf("AF%drate",$class); - print "$TC class add $DEV parent 2:0 classid 2:$class cbq ". - "bandwidth $linerate rate $rate_table{$AFrate} avpkt 1000 prio ". - (6-$class)." bounded allot 1514 weight 1 maxburst 21\n"; - print "$TC filter add $DEV parent 2:0 protocol ip prio 1 handle $class ". - "tcindex classid 2:$class\n"; - print "$TC qdisc add $DEV parent 2:$class gred setup DPs 3 default 2 ". - "$GRIO\n"; -# -# per DP setup -# - for $drop (1..3) { - print "\n# --- AF Class $class DP $drop---\n"; - $dscp = $class*8+$drop*2; - $tcindex = sprintf("1%x%x",$class,$drop); - print "$TC filter add $DEV parent 1:0 protocol ip prio 1 ". - "handle $dscp tcindex classid 1:$tcindex\n"; - $prob = $drop*0.02; - if ($GRIO) { - $gprio = $drop+1; - print "$TC qdisc change $DEV parent 2:$class gred limit 60KB min 15KB ". - "max 45KB burst 20 avpkt 1000 bandwidth $linerate DP $drop ". - "probability $prob ". - "prio $gprio\n"; - } else { - print "$TC qdisc change $DEV parent 2:$class gred limit 60KB min 15KB ". - "max 45KB burst 20 avpkt 1000 bandwidth $linerate DP $drop ". - "probability $prob \n"; - } - } -} -# -# -print "\n#------BE Queue setup------\n"; -print "$TC filter add $DEV parent 1:0 protocol ip prio 2 ". - "handle 0 tcindex mask 0 classid 1:1\n"; -print "$TC class add $DEV parent 2:0 classid 2:$beclass cbq ". - "bandwidth $linerate rate $berate avpkt 1000 prio 6 " . - "bounded allot 1514 weight 1 maxburst 21 \n"; -print "$TC filter add $DEV parent 2:0 protocol ip prio 1 handle 0 tcindex ". - "classid 2:5\n"; -print "$TC qdisc add $DEV parent 2:5 red limit 60KB min 15KB max 45KB ". - "burst 20 avpkt 1000 bandwidth $linerate probability 0.4\n"; diff --git a/examples/diffserv/ef-prio b/examples/diffserv/ef-prio deleted file mode 100644 index 48611bd..0000000 --- a/examples/diffserv/ef-prio +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/perl -$TC = "/root/DS-6-beta/iproute2-990530-dsing/tc/tc"; -$DEV = "dev eth1"; -$efrate="1.5Mbit"; -$MTU="1.5kB"; -print "$TC qdisc add $DEV handle 1:0 root dsmark indices 64 set_tc_index\n"; -print "$TC filter add $DEV parent 1:0 protocol ip prio 1 tcindex ". - "mask 0xfc shift 2\n"; -print "$TC qdisc add $DEV parent 1:0 handle 2:0 prio\n"; -# -# EF class: Maximum about one MTU sized packet allowed on the queue -# -print "$TC qdisc add $DEV parent 2:1 tbf rate $efrate burst $MTU limit 1.6kB\n"; -print "$TC filter add $DEV parent 2:0 protocol ip prio 1 ". - "handle 0x2e tcindex classid 2:1 pass_on\n"; -# -# BE class -# -print "#BE class(2:2) \n"; -print "$TC qdisc add $DEV parent 2:2 red limit 60KB ". - "min 15KB max 45KB burst 20 avpkt 1000 bandwidth 10Mbit ". - "probability 0.4\n"; -# -print "$TC filter add $DEV parent 2:0 protocol ip prio 2 ". - "handle 0 tcindex mask 0 classid 2:2 pass_on\n"; diff --git a/examples/diffserv/efcbq b/examples/diffserv/efcbq deleted file mode 100644 index bcc437b..0000000 --- a/examples/diffserv/efcbq +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/perl -# -$TC = "/root/DS-6-beta/iproute2-990530-dsing/tc/tc"; -$DEV = "dev eth1"; -print "$TC qdisc add $DEV handle 1:0 root dsmark indices 64 set_tc_index\n"; -print "$TC filter add $DEV parent 1:0 protocol ip prio 1 tcindex ". - "mask 0xfc shift 2\n"; -print "$TC qdisc add $DEV parent 1:0 handle 2:0 cbq bandwidth ". - "10Mbit cell 8 avpkt 1000 mpu 64\n"; -# -# EF class -# -print "$TC class add $DEV parent 2:0 classid 2:1 cbq bandwidth ". - "10Mbit rate 1500Kbit avpkt 1000 prio 1 bounded isolated ". - "allot 1514 weight 1 maxburst 10 \n"; -# packet fifo for EF? -print "$TC qdisc add $DEV parent 2:1 pfifo limit 5\n"; -print "$TC filter add $DEV parent 2:0 protocol ip prio 1 ". - "handle 0x2e tcindex classid 2:1 pass_on\n"; -# -# BE class -# -print "#BE class(2:2) \n"; -print "$TC class add $DEV parent 2:0 classid 2:2 cbq bandwidth ". - "10Mbit rate 5Mbit avpkt 1000 prio 7 allot 1514 weight 1 ". - "maxburst 21 borrow split 2:0 defmap 0xffff \n"; -print "$TC qdisc add $DEV parent 2:2 red limit 60KB ". - "min 15KB max 45KB burst 20 avpkt 1000 bandwidth 10Mbit ". - "probability 0.4\n"; -print "$TC filter add $DEV parent 2:0 protocol ip prio 2 ". - "handle 0 tcindex mask 0 classid 2:2 pass_on\n"; diff --git a/examples/diffserv/regression-testing b/examples/diffserv/regression-testing deleted file mode 100644 index 0ec705c..0000000 --- a/examples/diffserv/regression-testing +++ /dev/null @@ -1,125 +0,0 @@ - -These were the tests done to validate the Diffserv scripts. -This document will be updated continously. If you do more -thorough validation testing please post the details to the -diffserv mailing list. -Nevertheless, these tests should serve for basic validation. - -AFCBQ, EFCBQ, EFPRIO ----------------------- - -generate all possible DSCPs and observe that they -get sent to the proper classes. In the case of AF also -to the correct Virtual Queues. - -Edge1 ------ -generate TOS values 0x0,0x10,0xbb each with IP addresses -10.2.0.24 (mark 1), 10.2.0.3 (mark2) and 10.2.0.30 (mark 3) -and observe that they get marked as expected. - -Edge2 ------ - --Repeat the tests in Edge1 --ftp with data direction from 10.2.0.2 - *observe that the metering/policing works correctly (and the marking - as well). In this case the mark used will be 3 - -Edge31-cb-chains ----------------- - --ftp with data direction from 10.2.0.2 - - *observe that the metering/policing works correctly (and the marking - as well). In this case the mark used will be 1. - - Metering: The data throughput should not exceed 2*CIR1 + 2*CIR2 - which is roughly: 5mbps - - Marking: the should be a variation of marked packets: - AF41(TOS=0x88) AF42(0x90) AF43(0x98) and BE (0x0) - -More tests required to see the interaction of several sources (other -than subnet 10.2.0.0/24). - -Edge31-ca-u32 --------------- - -Generate data using modified tcpblast from 10.2.0.2 (behind eth2) to the -discard port of 10.1.0.2 (behind eth1) - -1) generate with src tos = 0x88 - Metering: Allocated throughput should not exceed 2*CIR1 + 2*CIR2 - approximately 5mbps - Marking: Should vary between 0x88,0x90,0x98 and 0x0 - -2) generate with src tos = 0x90 - Metering: Allocated throughput should not exceed CIR1 + 2*CIR2 - approximately 3.5mbps - Marking: Should vary between 0x90,0x98 and 0x0 - -3) generate with src tos = 0x98 - Metering: Allocated throughput should not exceed CIR1 + CIR2 - approximately 2.5mbps - Marking: Should vary between 0x98 and 0x0 - -4) generate with src tos any other than the above - Metering: Allocated throughput should not exceed CIR1 - approximately 1.5mbps - Marking: Should be consistent at 0x0 - -TODO: Testing on how each color shares when all 4 types of packets -are going through the edge device - -Edge32-cb-u32, Edge32-cb-chains -------------------------------- - --ftp with data direction from 10.2.0.2 - - *observe that the metering/policing works correctly (and the marking - as well). - - Metering: - The data throughput should not exceed 2*CIR1 + 2*CIR2 - + 2*PIR2 + PIR1 for u32 which is roughly: 6mbps - The data throughput should not exceed 2*CIR1 + 5*CIR2 - for chains which is roughly: 6mbps - - Marking: the should be a variation of marked packets: - AF41(TOS=0x88) AF42(0x90) AF43(0x98) and BE (0x0) - -TODO: --More tests required to see the interaction of several sources (other -than subnet 10.2.0.0/24). --More tests needed to capture stats on how many times the CIR was exceeded -but the data was not remarked etc. - -Edge32-ca-u32 --------------- - -Generate data using modified tcpblast from 10.2.0.2 (behind eth2) to the -discard port of 10.1.0.2 (behind eth1) - -1) generate with src tos = 0x88 - Metering: Allocated throughput should not exceed 2*CIR1 + 2*CIR2 - +PIR1 -- approximately 4mbps - Marking: Should vary between 0x88,0x90,0x98 and 0x0 - -2) generate with src tos = 0x90 - Metering: Allocated throughput should not exceed CIR1 + 2*CIR2 - + 2* PIR2 approximately 3mbps - Marking: Should vary between 0x90,0x98 and 0x0 - -3) generate with src tos = 0x98 - Metering: Allocated throughput should not exceed PIR1+ CIR1 + CIR2 - approximately 2.5mbps - Marking: Should vary between 0x98 and 0x0 - -4) generate with src tos any other than the above - Metering: Allocated throughput should not exceed CIR1 - approximately 1mbps - Marking: Should be consistent at 0x0 - -TODO: Testing on how each color shares when all 4 types of packets -are going through the edge device diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h deleted file mode 100644 index 9438c0f..0000000 --- a/include/SNAPSHOT.h +++ /dev/null @@ -1 +0,0 @@ -static char SNAPSHOT[] = "060323"; diff --git a/include/ip6tables.h b/include/ip6tables.h deleted file mode 100644 index 8360617..0000000 --- a/include/ip6tables.h +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef _IP6TABLES_USER_H -#define _IP6TABLES_USER_H - -#include "iptables_common.h" -#include "libiptc/libip6tc.h" - -struct ip6tables_rule_match -{ - struct ip6tables_rule_match *next; - - struct ip6tables_match *match; -}; - -/* Include file for additions: new matches and targets. */ -struct ip6tables_match -{ - struct ip6tables_match *next; - - ip6t_chainlabel name; - - const char *version; - - /* Size of match data. */ - size_t size; - - /* Size of match data relevent for userspace comparison purposes */ - size_t userspacesize; - - /* Function which prints out usage message. */ - void (*help)(void); - - /* Initialize the match. */ - void (*init)(struct ip6t_entry_match *m, unsigned int *nfcache); - - /* Function which parses command options; returns true if it - ate an option */ - int (*parse)(int c, char **argv, int invert, unsigned int *flags, - const struct ip6t_entry *entry, - unsigned int *nfcache, - struct ip6t_entry_match **match); - - /* Final check; exit if not ok. */ - void (*final_check)(unsigned int flags); - - /* Prints out the match iff non-NULL: put space at end */ - void (*print)(const struct ip6t_ip6 *ip, - const struct ip6t_entry_match *match, int numeric); - - /* Saves the union ipt_matchinfo in parsable form to stdout. */ - void (*save)(const struct ip6t_ip6 *ip, - const struct ip6t_entry_match *match); - - /* Pointer to list of extra command-line options */ - const struct option *extra_opts; - - /* Ignore these men behind the curtain: */ - unsigned int option_offset; - struct ip6t_entry_match *m; - unsigned int mflags; -#ifdef NO_SHARED_LIBS - unsigned int loaded; /* simulate loading so options are merged properly */ -#endif -}; - -struct ip6tables_target -{ - struct ip6tables_target *next; - - ip6t_chainlabel name; - - const char *version; - - /* Size of target data. */ - size_t size; - - /* Size of target data relevent for userspace comparison purposes */ - size_t userspacesize; - - /* Function which prints out usage message. */ - void (*help)(void); - - /* Initialize the target. */ - void (*init)(struct ip6t_entry_target *t, unsigned int *nfcache); - - /* Function which parses command options; returns true if it - ate an option */ - int (*parse)(int c, char **argv, int invert, unsigned int *flags, - const struct ip6t_entry *entry, - struct ip6t_entry_target **target); - - /* Final check; exit if not ok. */ - void (*final_check)(unsigned int flags); - - /* Prints out the target iff non-NULL: put space at end */ - void (*print)(const struct ip6t_ip6 *ip, - const struct ip6t_entry_target *target, int numeric); - - /* Saves the targinfo in parsable form to stdout. */ - void (*save)(const struct ip6t_ip6 *ip, - const struct ip6t_entry_target *target); - - /* Pointer to list of extra command-line options */ - struct option *extra_opts; - - /* Ignore these men behind the curtain: */ - unsigned int option_offset; - struct ip6t_entry_target *t; - unsigned int tflags; - unsigned int used; -#ifdef NO_SHARED_LIBS - unsigned int loaded; /* simulate loading so options are merged properly */ -#endif -}; - -extern int line; - -/* Your shared library should call one of these. */ -extern void register_match6(struct ip6tables_match *me); -extern void register_target6(struct ip6tables_target *me); - -extern int do_command6(int argc, char *argv[], char **table, - ip6tc_handle_t *handle); -/* Keeping track of external matches and targets: linked lists. */ -extern struct ip6tables_match *ip6tables_matches; -extern struct ip6tables_target *ip6tables_targets; - -enum ip6t_tryload { - DONT_LOAD, - TRY_LOAD, - LOAD_MUST_SUCCEED -}; - -extern struct ip6tables_target *find_target(const char *name, enum ip6t_tryload); -extern struct ip6tables_match *find_match(const char *name, enum ip6t_tryload, struct ip6tables_rule_match **match); - -extern int for_each_chain(int (*fn)(const ip6t_chainlabel, int, ip6tc_handle_t *), int verbose, int builtinstoo, ip6tc_handle_t *handle); -extern int flush_entries(const ip6t_chainlabel chain, int verbose, ip6tc_handle_t *handle); -extern int delete_chain(const ip6t_chainlabel chain, int verbose, ip6tc_handle_t *handle); -extern int ip6tables_insmod(const char *modname, const char *modprobe); - -#endif /*_IP6TABLES_USER_H*/ diff --git a/include/iptables.h b/include/iptables.h deleted file mode 100644 index 25f36ae..0000000 --- a/include/iptables.h +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef _IPTABLES_USER_H -#define _IPTABLES_USER_H - -#include "iptables_common.h" -#include "libiptc/libiptc.h" - -#ifndef IPT_LIB_DIR -#define IPT_LIB_DIR "/usr/local/lib/iptables" -#endif - -#ifndef IPPROTO_SCTP -#define IPPROTO_SCTP 132 -#endif - -#ifndef IPT_SO_GET_REVISION_MATCH /* Old kernel source. */ -#define IPT_SO_GET_REVISION_MATCH (IPT_BASE_CTL + 2) -#define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3) - -struct ipt_get_revision -{ - char name[IPT_FUNCTION_MAXNAMELEN-1]; - - u_int8_t revision; -}; -#endif /* IPT_SO_GET_REVISION_MATCH Old kernel source */ - -struct iptables_rule_match -{ - struct iptables_rule_match *next; - - struct iptables_match *match; -}; - -/* Include file for additions: new matches and targets. */ -struct iptables_match -{ - struct iptables_match *next; - - ipt_chainlabel name; - - /* Revision of match (0 by default). */ - u_int8_t revision; - - const char *version; - - /* Size of match data. */ - size_t size; - - /* Size of match data relevent for userspace comparison purposes */ - size_t userspacesize; - - /* Function which prints out usage message. */ - void (*help)(void); - - /* Initialize the match. */ - void (*init)(struct ipt_entry_match *m, unsigned int *nfcache); - - /* Function which parses command options; returns true if it - ate an option */ - int (*parse)(int c, char **argv, int invert, unsigned int *flags, - const struct ipt_entry *entry, - unsigned int *nfcache, - struct ipt_entry_match **match); - - /* Final check; exit if not ok. */ - void (*final_check)(unsigned int flags); - - /* Prints out the match iff non-NULL: put space at end */ - void (*print)(const struct ipt_ip *ip, - const struct ipt_entry_match *match, int numeric); - - /* Saves the match info in parsable form to stdout. */ - void (*save)(const struct ipt_ip *ip, - const struct ipt_entry_match *match); - - /* Pointer to list of extra command-line options */ - const struct option *extra_opts; - - /* Ignore these men behind the curtain: */ - unsigned int option_offset; - struct ipt_entry_match *m; - unsigned int mflags; -#ifdef NO_SHARED_LIBS - unsigned int loaded; /* simulate loading so options are merged properly */ -#endif -}; - -struct iptables_target -{ - struct iptables_target *next; - - ipt_chainlabel name; - - /* Revision of target (0 by default). */ - u_int8_t revision; - - const char *version; - - /* Size of target data. */ - size_t size; - - /* Size of target data relevent for userspace comparison purposes */ - size_t userspacesize; - - /* Function which prints out usage message. */ - void (*help)(void); - - /* Initialize the target. */ - void (*init)(struct ipt_entry_target *t, unsigned int *nfcache); - - /* Function which parses command options; returns true if it - ate an option */ - int (*parse)(int c, char **argv, int invert, unsigned int *flags, - const struct ipt_entry *entry, - struct ipt_entry_target **target); - - /* Final check; exit if not ok. */ - void (*final_check)(unsigned int flags); - - /* Prints out the target iff non-NULL: put space at end */ - void (*print)(const struct ipt_ip *ip, - const struct ipt_entry_target *target, int numeric); - - /* Saves the targinfo in parsable form to stdout. */ - void (*save)(const struct ipt_ip *ip, - const struct ipt_entry_target *target); - - /* Pointer to list of extra command-line options */ - struct option *extra_opts; - - /* Ignore these men behind the curtain: */ - unsigned int option_offset; - struct ipt_entry_target *t; - unsigned int tflags; - unsigned int used; -#ifdef NO_SHARED_LIBS - unsigned int loaded; /* simulate loading so options are merged properly */ -#endif -}; - -extern int line; - -/* Your shared library should call one of these. */ -extern void register_match(struct iptables_match *me); -extern void register_target(struct iptables_target *me); - -extern struct in_addr *dotted_to_addr(const char *dotted); -extern char *addr_to_dotted(const struct in_addr *addrp); -extern char *addr_to_anyname(const struct in_addr *addr); -extern char *mask_to_dotted(const struct in_addr *mask); - -extern void parse_hostnetworkmask(const char *name, struct in_addr **addrpp, - struct in_addr *maskp, unsigned int *naddrs); -extern u_int16_t parse_protocol(const char *s); - -extern int do_command(int argc, char *argv[], char **table, - iptc_handle_t *handle); -/* Keeping track of external matches and targets: linked lists. */ -extern struct iptables_match *iptables_matches; -extern struct iptables_target *iptables_targets; - -enum ipt_tryload { - DONT_LOAD, - TRY_LOAD, - LOAD_MUST_SUCCEED -}; - -extern struct iptables_target *find_target(const char *name, enum ipt_tryload); -extern struct iptables_match *find_match(const char *name, enum ipt_tryload, struct iptables_rule_match **match); - -extern int delete_chain(const ipt_chainlabel chain, int verbose, - iptc_handle_t *handle); -extern int flush_entries(const ipt_chainlabel chain, int verbose, - iptc_handle_t *handle); -extern int for_each_chain(int (*fn)(const ipt_chainlabel, int, iptc_handle_t *), - int verbose, int builtinstoo, iptc_handle_t *handle); -#endif /*_IPTABLES_USER_H*/ diff --git a/include/iptables_common.h b/include/iptables_common.h deleted file mode 100644 index ed5b9c0..0000000 --- a/include/iptables_common.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _IPTABLES_COMMON_H -#define _IPTABLES_COMMON_H -/* Shared definitions between ipv4 and ipv6. */ - -enum exittype { - OTHER_PROBLEM = 1, - PARAMETER_PROBLEM, - VERSION_PROBLEM -}; -extern void exit_printhelp(void) __attribute__((noreturn)); -extern void exit_tryhelp(int) __attribute__((noreturn)); -int check_inverse(const char option[], int *invert, int *optind, int argc); -extern int string_to_number(const char *, - unsigned int, - unsigned int, - unsigned int *); -extern int string_to_number_l(const char *, - unsigned long int, - unsigned long int, - unsigned long *); -extern int string_to_number_ll(const char *, - unsigned long long int, - unsigned long long int, - unsigned long long *); -extern int iptables_insmod(const char *modname, const char *modprobe); -void exit_error(enum exittype, char *, ...)__attribute__((noreturn, - format(printf,2,3))); -extern const char *program_name, *program_version; -extern char *lib_dir; - -#ifdef NO_SHARED_LIBS -# ifdef _INIT -# define _init _INIT -# endif - extern void init_extensions(void); -#endif - -#endif /*_IPTABLES_COMMON_H*/ diff --git a/include/libiptc/ipt_kernel_headers.h b/include/libiptc/ipt_kernel_headers.h deleted file mode 100644 index 18861fe..0000000 --- a/include/libiptc/ipt_kernel_headers.h +++ /dev/null @@ -1,27 +0,0 @@ -/* This is the userspace/kernel interface for Generic IP Chains, - required for libc6. */ -#ifndef _FWCHAINS_KERNEL_HEADERS_H -#define _FWCHAINS_KERNEL_HEADERS_H - -#include <limits.h> - -#if defined(__GLIBC__) && __GLIBC__ == 2 -#include <netinet/ip.h> -#include <netinet/in.h> -#include <netinet/ip_icmp.h> -#include <netinet/tcp.h> -#include <netinet/udp.h> -#include <net/if.h> -#include <sys/types.h> -#else /* libc5 */ -#include <sys/socket.h> -#include <linux/ip.h> -#include <linux/in.h> -#include <linux/if.h> -#include <linux/icmp.h> -#include <linux/tcp.h> -#include <linux/udp.h> -#include <linux/types.h> -#include <linux/in6.h> -#endif -#endif diff --git a/include/libiptc/libip6tc.h b/include/libiptc/libip6tc.h deleted file mode 100644 index 7a247c4..0000000 --- a/include/libiptc/libip6tc.h +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef _LIBIP6TC_H -#define _LIBIP6TC_H -/* Library which manipulates firewall rules. Version 0.2. */ - -#include <libiptc/ipt_kernel_headers.h> -#include <linux/netfilter_ipv6/ip6_tables.h> - -#ifndef IP6T_MIN_ALIGN -#define IP6T_MIN_ALIGN (__alignof__(struct ip6t_entry)) -#endif -#define IP6T_ALIGN(s) (((s) + (IP6T_MIN_ALIGN-1)) & ~(IP6T_MIN_ALIGN-1)) - -typedef char ip6t_chainlabel[32]; - -#define IP6TC_LABEL_ACCEPT "ACCEPT" -#define IP6TC_LABEL_DROP "DROP" -#define IP6TC_LABEL_QUEUE "QUEUE" -#define IP6TC_LABEL_RETURN "RETURN" - -/* Transparent handle type. */ -typedef struct ip6tc_handle *ip6tc_handle_t; - -/* Does this chain exist? */ -int ip6tc_is_chain(const char *chain, const ip6tc_handle_t handle); - -/* Take a snapshot of the rules. Returns NULL on error. */ -ip6tc_handle_t ip6tc_init(const char *tablename); - -/* Cleanup after ip6tc_init(). */ -void ip6tc_free(ip6tc_handle_t *h); - -/* Iterator functions to run through the chains. Returns NULL at end. */ -const char *ip6tc_first_chain(ip6tc_handle_t *handle); -const char *ip6tc_next_chain(ip6tc_handle_t *handle); - -/* Get first rule in the given chain: NULL for empty chain. */ -const struct ip6t_entry *ip6tc_first_rule(const char *chain, - ip6tc_handle_t *handle); - -/* Returns NULL when rules run out. */ -const struct ip6t_entry *ip6tc_next_rule(const struct ip6t_entry *prev, - ip6tc_handle_t *handle); - -/* Returns a pointer to the target name of this position. */ -const char *ip6tc_get_target(const struct ip6t_entry *e, - ip6tc_handle_t *handle); - -/* Is this a built-in chain? */ -int ip6tc_builtin(const char *chain, const ip6tc_handle_t handle); - -/* Get the policy of a given built-in chain */ -const char *ip6tc_get_policy(const char *chain, - struct ip6t_counters *counters, - ip6tc_handle_t *handle); - -/* These functions return TRUE for OK or 0 and set errno. If errno == - 0, it means there was a version error (ie. upgrade libiptc). */ -/* Rule numbers start at 1 for the first rule. */ - -/* Insert the entry `fw' in chain `chain' into position `rulenum'. */ -int ip6tc_insert_entry(const ip6t_chainlabel chain, - const struct ip6t_entry *e, - unsigned int rulenum, - ip6tc_handle_t *handle); - -/* Atomically replace rule `rulenum' in `chain' with `fw'. */ -int ip6tc_replace_entry(const ip6t_chainlabel chain, - const struct ip6t_entry *e, - unsigned int rulenum, - ip6tc_handle_t *handle); - -/* Append entry `fw' to chain `chain'. Equivalent to insert with - rulenum = length of chain. */ -int ip6tc_append_entry(const ip6t_chainlabel chain, - const struct ip6t_entry *e, - ip6tc_handle_t *handle); - -/* Delete the first rule in `chain' which matches `fw'. */ -int ip6tc_delete_entry(const ip6t_chainlabel chain, - const struct ip6t_entry *origfw, - unsigned char *matchmask, - ip6tc_handle_t *handle); - -/* Delete the rule in position `rulenum' in `chain'. */ -int ip6tc_delete_num_entry(const ip6t_chainlabel chain, - unsigned int rulenum, - ip6tc_handle_t *handle); - -/* Check the packet `fw' on chain `chain'. Returns the verdict, or - NULL and sets errno. */ -const char *ip6tc_check_packet(const ip6t_chainlabel chain, - struct ip6t_entry *, - ip6tc_handle_t *handle); - -/* Flushes the entries in the given chain (ie. empties chain). */ -int ip6tc_flush_entries(const ip6t_chainlabel chain, - ip6tc_handle_t *handle); - -/* Zeroes the counters in a chain. */ -int ip6tc_zero_entries(const ip6t_chainlabel chain, - ip6tc_handle_t *handle); - -/* Creates a new chain. */ -int ip6tc_create_chain(const ip6t_chainlabel chain, - ip6tc_handle_t *handle); - -/* Deletes a chain. */ -int ip6tc_delete_chain(const ip6t_chainlabel chain, - ip6tc_handle_t *handle); - -/* Renames a chain. */ -int ip6tc_rename_chain(const ip6t_chainlabel oldname, - const ip6t_chainlabel newname, - ip6tc_handle_t *handle); - -/* Sets the policy on a built-in chain. */ -int ip6tc_set_policy(const ip6t_chainlabel chain, - const ip6t_chainlabel policy, - struct ip6t_counters *counters, - ip6tc_handle_t *handle); - -/* Get the number of references to this chain */ -int ip6tc_get_references(unsigned int *ref, const ip6t_chainlabel chain, - ip6tc_handle_t *handle); - -/* read packet and byte counters for a specific rule */ -struct ip6t_counters *ip6tc_read_counter(const ip6t_chainlabel chain, - unsigned int rulenum, - ip6tc_handle_t *handle); - -/* zero packet and byte counters for a specific rule */ -int ip6tc_zero_counter(const ip6t_chainlabel chain, - unsigned int rulenum, - ip6tc_handle_t *handle); - -/* set packet and byte counters for a specific rule */ -int ip6tc_set_counter(const ip6t_chainlabel chain, - unsigned int rulenum, - struct ip6t_counters *counters, - ip6tc_handle_t *handle); - -/* Makes the actual changes. */ -int ip6tc_commit(ip6tc_handle_t *handle); - -/* Get raw socket. */ -int ip6tc_get_raw_socket(); - -/* Translates errno numbers into more human-readable form than strerror. */ -const char *ip6tc_strerror(int err); - -/* Return prefix length, or -1 if not contiguous */ -int ipv6_prefix_length(const struct in6_addr *a); - -#endif /* _LIBIP6TC_H */ diff --git a/include/libiptc/libiptc.h b/include/libiptc/libiptc.h deleted file mode 100644 index 7628bda..0000000 --- a/include/libiptc/libiptc.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef _LIBIPTC_H -#define _LIBIPTC_H -/* Library which manipulates filtering rules. */ - -#include <libiptc/ipt_kernel_headers.h> -#include <linux/netfilter_ipv4/ip_tables.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef IPT_MIN_ALIGN -/* ipt_entry has pointers and u_int64_t's in it, so if you align to - it, you'll also align to any crazy matches and targets someone - might write */ -#define IPT_MIN_ALIGN (__alignof__(struct ipt_entry)) -#endif - -#define IPT_ALIGN(s) (((s) + ((IPT_MIN_ALIGN)-1)) & ~((IPT_MIN_ALIGN)-1)) - -typedef char ipt_chainlabel[32]; - -#define IPTC_LABEL_ACCEPT "ACCEPT" -#define IPTC_LABEL_DROP "DROP" -#define IPTC_LABEL_QUEUE "QUEUE" -#define IPTC_LABEL_RETURN "RETURN" - -/* Transparent handle type. */ -typedef struct iptc_handle *iptc_handle_t; - -/* Does this chain exist? */ -int iptc_is_chain(const char *chain, const iptc_handle_t handle); - -/* Take a snapshot of the rules. Returns NULL on error. */ -iptc_handle_t iptc_init(const char *tablename); - -/* Cleanup after iptc_init(). */ -void iptc_free(iptc_handle_t *h); - -/* Iterator functions to run through the chains. Returns NULL at end. */ -const char *iptc_first_chain(iptc_handle_t *handle); -const char *iptc_next_chain(iptc_handle_t *handle); - -/* Get first rule in the given chain: NULL for empty chain. */ -const struct ipt_entry *iptc_first_rule(const char *chain, - iptc_handle_t *handle); - -/* Returns NULL when rules run out. */ -const struct ipt_entry *iptc_next_rule(const struct ipt_entry *prev, - iptc_handle_t *handle); - -/* Returns a pointer to the target name of this entry. */ -const char *iptc_get_target(const struct ipt_entry *e, - iptc_handle_t *handle); - -/* Is this a built-in chain? */ -int iptc_builtin(const char *chain, const iptc_handle_t handle); - -/* Get the policy of a given built-in chain */ -const char *iptc_get_policy(const char *chain, - struct ipt_counters *counter, - iptc_handle_t *handle); - -/* These functions return TRUE for OK or 0 and set errno. If errno == - 0, it means there was a version error (ie. upgrade libiptc). */ -/* Rule numbers start at 1 for the first rule. */ - -/* Insert the entry `e' in chain `chain' into position `rulenum'. */ -int iptc_insert_entry(const ipt_chainlabel chain, - const struct ipt_entry *e, - unsigned int rulenum, - iptc_handle_t *handle); - -/* Atomically replace rule `rulenum' in `chain' with `e'. */ -int iptc_replace_entry(const ipt_chainlabel chain, - const struct ipt_entry *e, - unsigned int rulenum, - iptc_handle_t *handle); - -/* Append entry `e' to chain `chain'. Equivalent to insert with - rulenum = length of chain. */ -int iptc_append_entry(const ipt_chainlabel chain, - const struct ipt_entry *e, - iptc_handle_t *handle); - -/* Delete the first rule in `chain' which matches `e', subject to - matchmask (array of length == origfw) */ -int iptc_delete_entry(const ipt_chainlabel chain, - const struct ipt_entry *origfw, - unsigned char *matchmask, - iptc_handle_t *handle); - -/* Delete the rule in position `rulenum' in `chain'. */ -int iptc_delete_num_entry(const ipt_chainlabel chain, - unsigned int rulenum, - iptc_handle_t *handle); - -/* Check the packet `e' on chain `chain'. Returns the verdict, or - NULL and sets errno. */ -const char *iptc_check_packet(const ipt_chainlabel chain, - struct ipt_entry *entry, - iptc_handle_t *handle); - -/* Flushes the entries in the given chain (ie. empties chain). */ -int iptc_flush_entries(const ipt_chainlabel chain, - iptc_handle_t *handle); - -/* Zeroes the counters in a chain. */ -int iptc_zero_entries(const ipt_chainlabel chain, - iptc_handle_t *handle); - -/* Creates a new chain. */ -int iptc_create_chain(const ipt_chainlabel chain, - iptc_handle_t *handle); - -/* Deletes a chain. */ -int iptc_delete_chain(const ipt_chainlabel chain, - iptc_handle_t *handle); - -/* Renames a chain. */ -int iptc_rename_chain(const ipt_chainlabel oldname, - const ipt_chainlabel newname, - iptc_handle_t *handle); - -/* Sets the policy on a built-in chain. */ -int iptc_set_policy(const ipt_chainlabel chain, - const ipt_chainlabel policy, - struct ipt_counters *counters, - iptc_handle_t *handle); - -/* Get the number of references to this chain */ -int iptc_get_references(unsigned int *ref, - const ipt_chainlabel chain, - iptc_handle_t *handle); - -/* read packet and byte counters for a specific rule */ -struct ipt_counters *iptc_read_counter(const ipt_chainlabel chain, - unsigned int rulenum, - iptc_handle_t *handle); - -/* zero packet and byte counters for a specific rule */ -int iptc_zero_counter(const ipt_chainlabel chain, - unsigned int rulenum, - iptc_handle_t *handle); - -/* set packet and byte counters for a specific rule */ -int iptc_set_counter(const ipt_chainlabel chain, - unsigned int rulenum, - struct ipt_counters *counters, - iptc_handle_t *handle); - -/* Makes the actual changes. */ -int iptc_commit(iptc_handle_t *handle); - -/* Get raw socket. */ -int iptc_get_raw_socket(void); - -/* Translates errno numbers into more human-readable form than strerror. */ -const char *iptc_strerror(int err); - -#ifdef __cplusplus -} -#endif - - -#endif /* _LIBIPTC_H */ diff --git a/include/libnetlink.h b/include/libnetlink.h deleted file mode 100644 index 63cc3c8..0000000 --- a/include/libnetlink.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef __LIBNETLINK_H__ -#define __LIBNETLINK_H__ 1 - -#include <asm/types.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> - -struct rtnl_handle -{ - int fd; - struct sockaddr_nl local; - struct sockaddr_nl peer; - __u32 seq; - __u32 dump; -}; - -extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions); -extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol); -extern void rtnl_close(struct rtnl_handle *rth); -extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type); -extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len); - -typedef int (*rtnl_filter_t)(const struct sockaddr_nl *, - struct nlmsghdr *n, void *); -extern int rtnl_dump_filter(struct rtnl_handle *rth, rtnl_filter_t filter, - void *arg1, - rtnl_filter_t junk, - void *arg2); -extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, - unsigned groups, struct nlmsghdr *answer, - rtnl_filter_t junk, - void *jarg); -extern int rtnl_send(struct rtnl_handle *rth, const char *buf, int); - - -extern int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data); -extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen); -extern int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len); -extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data); -extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, const void *data, int alen); - -extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len); -extern int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len); - -#define parse_rtattr_nested(tb, max, rta) \ - (parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))) - -extern int rtnl_listen(struct rtnl_handle *, rtnl_filter_t handler, - void *jarg); -extern int rtnl_from_file(FILE *, rtnl_filter_t handler, - void *jarg); - -#define NLMSG_TAIL(nmsg) \ - ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) - -#endif /* __LIBNETLINK_H__ */ - diff --git a/include/linux/gen_stats.h b/include/linux/gen_stats.h deleted file mode 100644 index 13f4e74..0000000 --- a/include/linux/gen_stats.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef __LINUX_GEN_STATS_H -#define __LINUX_GEN_STATS_H - -#include <linux/types.h> - -enum { - TCA_STATS_UNSPEC, - TCA_STATS_BASIC, - TCA_STATS_RATE_EST, - TCA_STATS_QUEUE, - TCA_STATS_APP, - __TCA_STATS_MAX, -}; -#define TCA_STATS_MAX (__TCA_STATS_MAX - 1) - -/** - * struct gnet_stats_basic - byte/packet throughput statistics - * @bytes: number of seen bytes - * @packets: number of seen packets - */ -struct gnet_stats_basic -{ - __u64 bytes; - __u32 packets; -}; - -/** - * struct gnet_stats_rate_est - rate estimator - * @bps: current byte rate - * @pps: current packet rate - */ -struct gnet_stats_rate_est -{ - __u32 bps; - __u32 pps; -}; - -/** - * struct gnet_stats_queue - queuing statistics - * @qlen: queue length - * @backlog: backlog size of queue - * @drops: number of dropped packets - * @requeues: number of requeues - * @overlimits: number of enqueues over the limit - */ -struct gnet_stats_queue -{ - __u32 qlen; - __u32 backlog; - __u32 drops; - __u32 requeues; - __u32 overlimits; -}; - -/** - * struct gnet_estimator - rate estimator configuration - * @interval: sampling period - * @ewma_log: the log of measurement window weight - */ -struct gnet_estimator -{ - signed char interval; - unsigned char ewma_log; -}; - - -#endif /* __LINUX_GEN_STATS_H */ diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h deleted file mode 100644 index 85d456d..0000000 --- a/include/linux/inet_diag.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef _INET_DIAG_H_ -#define _INET_DIAG_H_ 1 - -/* Just some random number */ -#define TCPDIAG_GETSOCK 18 -#define DCCPDIAG_GETSOCK 19 - -#define INET_DIAG_GETSOCK_MAX 24 - -/* Socket identity */ -struct inet_diag_sockid { - __u16 idiag_sport; - __u16 idiag_dport; - __u32 idiag_src[4]; - __u32 idiag_dst[4]; - __u32 idiag_if; - __u32 idiag_cookie[2]; -#define INET_DIAG_NOCOOKIE (~0U) -}; - -/* Request structure */ - -struct inet_diag_req { - __u8 idiag_family; /* Family of addresses. */ - __u8 idiag_src_len; - __u8 idiag_dst_len; - __u8 idiag_ext; /* Query extended information */ - - struct inet_diag_sockid id; - - __u32 idiag_states; /* States to dump */ - __u32 idiag_dbs; /* Tables to dump (NI) */ -}; - -enum { - INET_DIAG_REQ_NONE, - INET_DIAG_REQ_BYTECODE, -}; - -#define INET_DIAG_REQ_MAX INET_DIAG_REQ_BYTECODE - -/* Bytecode is sequence of 4 byte commands followed by variable arguments. - * All the commands identified by "code" are conditional jumps forward: - * to offset cc+"yes" or to offset cc+"no". "yes" is supposed to be - * length of the command and its arguments. - */ - -struct inet_diag_bc_op { - unsigned char code; - unsigned char yes; - unsigned short no; -}; - -enum { - INET_DIAG_BC_NOP, - INET_DIAG_BC_JMP, - INET_DIAG_BC_S_GE, - INET_DIAG_BC_S_LE, - INET_DIAG_BC_D_GE, - INET_DIAG_BC_D_LE, - INET_DIAG_BC_AUTO, - INET_DIAG_BC_S_COND, - INET_DIAG_BC_D_COND, -}; - -struct inet_diag_hostcond { - __u8 family; - __u8 prefix_len; - int port; - __u32 addr[0]; -}; - -/* Base info structure. It contains socket identity (addrs/ports/cookie) - * and, alas, the information shown by netstat. */ -struct inet_diag_msg { - __u8 idiag_family; - __u8 idiag_state; - __u8 idiag_timer; - __u8 idiag_retrans; - - struct inet_diag_sockid id; - - __u32 idiag_expires; - __u32 idiag_rqueue; - __u32 idiag_wqueue; - __u32 idiag_uid; - __u32 idiag_inode; -}; - -/* Extensions */ - -enum { - INET_DIAG_NONE, - INET_DIAG_MEMINFO, - INET_DIAG_INFO, - INET_DIAG_VEGASINFO, - INET_DIAG_CONG, -}; - -#define INET_DIAG_MAX INET_DIAG_CONG - - -/* INET_DIAG_MEM */ - -struct inet_diag_meminfo { - __u32 idiag_rmem; - __u32 idiag_wmem; - __u32 idiag_fmem; - __u32 idiag_tmem; -}; - -/* INET_DIAG_VEGASINFO */ - -struct tcpvegas_info { - __u32 tcpv_enabled; - __u32 tcpv_rttcnt; - __u32 tcpv_rtt; - __u32 tcpv_minrtt; -}; - - -#endif /* _INET_DIAG_H_ */ diff --git a/include/linux/ip_mp_alg.h b/include/linux/ip_mp_alg.h deleted file mode 100644 index e234e20..0000000 --- a/include/linux/ip_mp_alg.h +++ /dev/null @@ -1,22 +0,0 @@ -/* ip_mp_alg.h: IPV4 multipath algorithm support, user-visible values. - * - * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com> - * Copyright (C) 2005 David S. Miller <davem@davemloft.net> - */ - -#ifndef _LINUX_IP_MP_ALG_H -#define _LINUX_IP_MP_ALG_H - -enum ip_mp_alg { - IP_MP_ALG_NONE, - IP_MP_ALG_RR, - IP_MP_ALG_DRR, - IP_MP_ALG_RANDOM, - IP_MP_ALG_WRANDOM, - __IP_MP_ALG_MAX -}; - -#define IP_MP_ALG_MAX (__IP_MP_ALG_MAX - 1) - -#endif /* _LINUX_IP_MP_ALG_H */ - diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h deleted file mode 100644 index 17d8eff..0000000 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ /dev/null @@ -1,346 +0,0 @@ -/* - * 25-Jul-1998 Major changes to allow for ip chain table - * - * 3-Jan-2000 Named tables to allow packet selection for different uses. - */ - -/* - * Format of an IP firewall descriptor - * - * src, dst, src_mask, dst_mask are always stored in network byte order. - * flags are stored in host byte order (of course). - * Port numbers are stored in HOST byte order. - */ - -#ifndef _IPTABLES_H -#define _IPTABLES_H - -#include <linux/netfilter_ipv4.h> - -#define IPT_FUNCTION_MAXNAMELEN 30 -#define IPT_TABLE_MAXNAMELEN 32 - -/* Yes, Virginia, you have to zero the padding. */ -struct ipt_ip { - /* Source and destination IP addr */ - struct in_addr src, dst; - /* Mask for src and dest IP addr */ - struct in_addr smsk, dmsk; - char iniface[IFNAMSIZ], outiface[IFNAMSIZ]; - unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ]; - - /* Protocol, 0 = ANY */ - u_int16_t proto; - - /* Flags word */ - u_int8_t flags; - /* Inverse flags */ - u_int8_t invflags; -}; - -struct ipt_entry_match -{ - union { - struct { - u_int16_t match_size; - - /* Used by userspace */ - char name[IPT_FUNCTION_MAXNAMELEN-1]; - - u_int8_t revision; - } user; - struct { - u_int16_t match_size; - - /* Used inside the kernel */ - struct ipt_match *match; - } kernel; - - /* Total length */ - u_int16_t match_size; - } u; - - unsigned char data[0]; -}; - -struct ipt_entry_target -{ - union { - struct { - u_int16_t target_size; - - /* Used by userspace */ - char name[IPT_FUNCTION_MAXNAMELEN-1]; - - u_int8_t revision; - } user; - struct { - u_int16_t target_size; - - /* Used inside the kernel */ - struct ipt_target *target; - } kernel; - - /* Total length */ - u_int16_t target_size; - } u; - - unsigned char data[0]; -}; - -struct ipt_standard_target -{ - struct ipt_entry_target target; - int verdict; -}; - -struct ipt_counters -{ - u_int64_t pcnt, bcnt; /* Packet and byte counters */ -}; - -/* Values for "flag" field in struct ipt_ip (general ip structure). */ -#define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ -#define IPT_F_MASK 0x01 /* All possible flag bits mask. */ - -/* Values for "inv" field in struct ipt_ip. */ -#define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */ -#define IPT_INV_VIA_OUT 0x02 /* Invert the sense of OUT IFACE */ -#define IPT_INV_TOS 0x04 /* Invert the sense of TOS. */ -#define IPT_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */ -#define IPT_INV_DSTIP 0x10 /* Invert the sense of DST OP. */ -#define IPT_INV_FRAG 0x20 /* Invert the sense of FRAG. */ -#define IPT_INV_PROTO 0x40 /* Invert the sense of PROTO. */ -#define IPT_INV_MASK 0x7F /* All possible flag bits mask. */ - -/* This structure defines each of the firewall rules. Consists of 3 - parts which are 1) general IP header stuff 2) match specific - stuff 3) the target to perform if the rule matches */ -struct ipt_entry -{ - struct ipt_ip ip; - - /* Mark with fields that we care about. */ - unsigned int nfcache; - - /* Size of ipt_entry + matches */ - u_int16_t target_offset; - /* Size of ipt_entry + matches + target */ - u_int16_t next_offset; - - /* Back pointer */ - unsigned int comefrom; - - /* Packet and byte counters. */ - struct ipt_counters counters; - - /* The matches (if any), then the target. */ - unsigned char elems[0]; -}; - -/* - * New IP firewall options for [gs]etsockopt at the RAW IP level. - * Unlike BSD Linux inherits IP options so you don't have to use a raw - * socket for this. Instead we check rights in the calls. */ -#define IPT_BASE_CTL 64 /* base for firewall socket options */ - -#define IPT_SO_SET_REPLACE (IPT_BASE_CTL) -#define IPT_SO_SET_ADD_COUNTERS (IPT_BASE_CTL + 1) -#define IPT_SO_SET_MAX IPT_SO_SET_ADD_COUNTERS - -#define IPT_SO_GET_INFO (IPT_BASE_CTL) -#define IPT_SO_GET_ENTRIES (IPT_BASE_CTL + 1) -#define IPT_SO_GET_REVISION_MATCH (IPT_BASE_CTL + 2) -#define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3) -#define IPT_SO_GET_MAX IPT_SO_GET_REVISION_TARGET - -/* CONTINUE verdict for targets */ -#define IPT_CONTINUE 0xFFFFFFFF - -/* For standard target */ -#define IPT_RETURN (-NF_MAX_VERDICT - 1) - -/* TCP matching stuff */ -struct ipt_tcp -{ - u_int16_t spts[2]; /* Source port range. */ - u_int16_t dpts[2]; /* Destination port range. */ - u_int8_t option; /* TCP Option iff non-zero*/ - u_int8_t flg_mask; /* TCP flags mask byte */ - u_int8_t flg_cmp; /* TCP flags compare byte */ - u_int8_t invflags; /* Inverse flags */ -}; - -/* Values for "inv" field in struct ipt_tcp. */ -#define IPT_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ -#define IPT_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ -#define IPT_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */ -#define IPT_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */ -#define IPT_TCP_INV_MASK 0x0F /* All possible flags. */ - -/* UDP matching stuff */ -struct ipt_udp -{ - u_int16_t spts[2]; /* Source port range. */ - u_int16_t dpts[2]; /* Destination port range. */ - u_int8_t invflags; /* Inverse flags */ -}; - -/* Values for "invflags" field in struct ipt_udp. */ -#define IPT_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ -#define IPT_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ -#define IPT_UDP_INV_MASK 0x03 /* All possible flags. */ - -/* ICMP matching stuff */ -struct ipt_icmp -{ - u_int8_t type; /* type to match */ - u_int8_t code[2]; /* range of code */ - u_int8_t invflags; /* Inverse flags */ -}; - -/* Values for "inv" field for struct ipt_icmp. */ -#define IPT_ICMP_INV 0x01 /* Invert the sense of type/code test */ - -/* The argument to IPT_SO_GET_INFO */ -struct ipt_getinfo -{ - /* Which table: caller fills this in. */ - char name[IPT_TABLE_MAXNAMELEN]; - - /* Kernel fills these in. */ - /* Which hook entry points are valid: bitmask */ - unsigned int valid_hooks; - - /* Hook entry points: one per netfilter hook. */ - unsigned int hook_entry[NF_IP_NUMHOOKS]; - - /* Underflow points. */ - unsigned int underflow[NF_IP_NUMHOOKS]; - - /* Number of entries */ - unsigned int num_entries; - - /* Size of entries. */ - unsigned int size; -}; - -/* The argument to IPT_SO_SET_REPLACE. */ -struct ipt_replace -{ - /* Which table. */ - char name[IPT_TABLE_MAXNAMELEN]; - - /* Which hook entry points are valid: bitmask. You can't - change this. */ - unsigned int valid_hooks; - - /* Number of entries */ - unsigned int num_entries; - - /* Total size of new entries */ - unsigned int size; - - /* Hook entry points. */ - unsigned int hook_entry[NF_IP_NUMHOOKS]; - - /* Underflow points. */ - unsigned int underflow[NF_IP_NUMHOOKS]; - - /* Information about old entries: */ - /* Number of counters (must be equal to current number of entries). */ - unsigned int num_counters; - - /* The old entries' counters. */ - struct ipt_counters *counters; - - /* The entries (hang off end: not really an array). */ - struct ipt_entry entries[0]; -}; - -/* The argument to IPT_SO_ADD_COUNTERS. */ -struct ipt_counters_info -{ - /* Which table. */ - char name[IPT_TABLE_MAXNAMELEN]; - - unsigned int num_counters; - - /* The counters (actually `number' of these). */ - struct ipt_counters counters[0]; -}; - -/* The argument to IPT_SO_GET_ENTRIES. */ -struct ipt_get_entries -{ - /* Which table: user fills this in. */ - char name[IPT_TABLE_MAXNAMELEN]; - - /* User fills this in: total entry size. */ - unsigned int size; - - /* The entries. */ - struct ipt_entry entrytable[0]; -}; - -/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision - * kernel supports, if >= revision. */ -struct ipt_get_revision -{ - char name[IPT_FUNCTION_MAXNAMELEN-1]; - - u_int8_t revision; -}; - -/* Standard return verdict, or do jump. */ -#define IPT_STANDARD_TARGET "" -/* Error verdict. */ -#define IPT_ERROR_TARGET "ERROR" - -/* Helper functions */ -static __inline__ struct ipt_entry_target * -ipt_get_target(struct ipt_entry *e) -{ - return (void *)e + e->target_offset; -} - -/* fn returns 0 to continue iteration */ -#define IPT_MATCH_ITERATE(e, fn, args...) \ -({ \ - unsigned int __i; \ - int __ret = 0; \ - struct ipt_entry_match *__match; \ - \ - for (__i = sizeof(struct ipt_entry); \ - __i < (e)->target_offset; \ - __i += __match->u.match_size) { \ - __match = (void *)(e) + __i; \ - \ - __ret = fn(__match , ## args); \ - if (__ret != 0) \ - break; \ - } \ - __ret; \ -}) - -/* fn returns 0 to continue iteration */ -#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ -({ \ - unsigned int __i; \ - int __ret = 0; \ - struct ipt_entry *__entry; \ - \ - for (__i = 0; __i < (size); __i += __entry->next_offset) { \ - __entry = (void *)(entries) + __i; \ - \ - __ret = fn(__entry , ## args); \ - if (__ret != 0) \ - break; \ - } \ - __ret; \ -}) - -/* - * Main firewall chains definitions and global var's definitions. - */ -#endif /* _IPTABLES_H */ diff --git a/include/linux/netlink.h b/include/linux/netlink.h deleted file mode 100644 index 24a38ae..0000000 --- a/include/linux/netlink.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef __LINUX_NETLINK_H -#define __LINUX_NETLINK_H - -#include <linux/socket.h> /* for sa_family_t */ -#include <linux/types.h> - -#define NETLINK_ROUTE 0 /* Routing/device hook */ -#define NETLINK_W1 1 /* 1-wire subsystem */ -#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */ -#define NETLINK_FIREWALL 3 /* Firewalling hook */ -#define NETLINK_INET_DIAG 4 /* INET socket monitoring */ -#define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */ -#define NETLINK_XFRM 6 /* ipsec */ -#define NETLINK_SELINUX 7 /* SELinux event notifications */ -#define NETLINK_ISCSI 8 /* Open-iSCSI */ -#define NETLINK_AUDIT 9 /* auditing */ -#define NETLINK_FIB_LOOKUP 10 -#define NETLINK_CONNECTOR 11 -#define NETLINK_NETFILTER 12 /* netfilter subsystem */ -#define NETLINK_IP6_FW 13 -#define NETLINK_DNRTMSG 14 /* DECnet routing messages */ -#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */ -#define NETLINK_GENERIC 16 - -#define MAX_LINKS 32 - -struct sockaddr_nl -{ - sa_family_t nl_family; /* AF_NETLINK */ - unsigned short nl_pad; /* zero */ - __u32 nl_pid; /* process pid */ - __u32 nl_groups; /* multicast groups mask */ -}; - -struct nlmsghdr -{ - __u32 nlmsg_len; /* Length of message including header */ - __u16 nlmsg_type; /* Message content */ - __u16 nlmsg_flags; /* Additional flags */ - __u32 nlmsg_seq; /* Sequence number */ - __u32 nlmsg_pid; /* Sending process PID */ -}; - -/* Flags values */ - -#define NLM_F_REQUEST 1 /* It is request message. */ -#define NLM_F_MULTI 2 /* Multipart message, terminated by NLMSG_DONE */ -#define NLM_F_ACK 4 /* Reply with ack, with zero or error code */ -#define NLM_F_ECHO 8 /* Echo this request */ - -/* Modifiers to GET request */ -#define NLM_F_ROOT 0x100 /* specify tree root */ -#define NLM_F_MATCH 0x200 /* return all matching */ -#define NLM_F_ATOMIC 0x400 /* atomic GET */ -#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH) - -/* Modifiers to NEW request */ -#define NLM_F_REPLACE 0x100 /* Override existing */ -#define NLM_F_EXCL 0x200 /* Do not touch, if it exists */ -#define NLM_F_CREATE 0x400 /* Create, if it does not exist */ -#define NLM_F_APPEND 0x800 /* Add to end of list */ - -/* - 4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL - 4.4BSD CHANGE NLM_F_REPLACE - - True CHANGE NLM_F_CREATE|NLM_F_REPLACE - Append NLM_F_CREATE - Check NLM_F_EXCL - */ - -#define NLMSG_ALIGNTO 4 -#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) -#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) -#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN)) -#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) -#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0))) -#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \ - (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len))) -#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \ - (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \ - (nlh)->nlmsg_len <= (len)) -#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len))) - -#define NLMSG_NOOP 0x1 /* Nothing. */ -#define NLMSG_ERROR 0x2 /* Error */ -#define NLMSG_DONE 0x3 /* End of a dump */ -#define NLMSG_OVERRUN 0x4 /* Data lost */ - -#define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */ - -struct nlmsgerr -{ - int error; - struct nlmsghdr msg; -}; - -#define NETLINK_ADD_MEMBERSHIP 1 -#define NETLINK_DROP_MEMBERSHIP 2 -#define NETLINK_PKTINFO 3 - -struct nl_pktinfo -{ - __u32 group; -}; - -#define NET_MAJOR 36 /* Major 36 is reserved for networking */ - -enum { - NETLINK_UNCONNECTED = 0, - NETLINK_CONNECTED, -}; - -/* - * <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)--> - * +---------------------+- - -+- - - - - - - - - -+- - -+ - * | Header | Pad | Payload | Pad | - * | (struct nlattr) | ing | | ing | - * +---------------------+- - -+- - - - - - - - - -+- - -+ - * <-------------- nlattr->nla_len --------------> - */ - -struct nlattr -{ - __u16 nla_len; - __u16 nla_type; -}; - -#define NLA_ALIGNTO 4 -#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1)) -#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) - - -#endif /* __LINUX_NETLINK_H */ diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h deleted file mode 100644 index bd2c5a2..0000000 --- a/include/linux/pkt_cls.h +++ /dev/null @@ -1,428 +0,0 @@ -#ifndef __LINUX_PKT_CLS_H -#define __LINUX_PKT_CLS_H - -#include <linux/pkt_sched.h> - -/* I think i could have done better macros ; for now this is stolen from - * some arch/mips code - jhs -*/ -#define _TC_MAKE32(x) ((x)) - -#define _TC_MAKEMASK1(n) (_TC_MAKE32(1) << _TC_MAKE32(n)) -#define _TC_MAKEMASK(v,n) (_TC_MAKE32((_TC_MAKE32(1)<<(v))-1) << _TC_MAKE32(n)) -#define _TC_MAKEVALUE(v,n) (_TC_MAKE32(v) << _TC_MAKE32(n)) -#define _TC_GETVALUE(v,n,m) ((_TC_MAKE32(v) & _TC_MAKE32(m)) >> _TC_MAKE32(n)) - -/* verdict bit breakdown - * -bit 0: when set -> this packet has been munged already - -bit 1: when set -> It is ok to munge this packet - -bit 2,3,4,5: Reclassify counter - sort of reverse TTL - if exceeded -assume loop - -bit 6,7: Where this packet was last seen -0: Above the transmit example at the socket level -1: on the Ingress -2: on the Egress - -bit 8: when set --> Request not to classify on ingress. - -bits 9,10,11: redirect counter - redirect TTL. Loop avoidance - - * - * */ - -#define TC_MUNGED _TC_MAKEMASK1(0) -#define SET_TC_MUNGED(v) ( TC_MUNGED | (v & ~TC_MUNGED)) -#define CLR_TC_MUNGED(v) ( v & ~TC_MUNGED) - -#define TC_OK2MUNGE _TC_MAKEMASK1(1) -#define SET_TC_OK2MUNGE(v) ( TC_OK2MUNGE | (v & ~TC_OK2MUNGE)) -#define CLR_TC_OK2MUNGE(v) ( v & ~TC_OK2MUNGE) - -#define S_TC_VERD _TC_MAKE32(2) -#define M_TC_VERD _TC_MAKEMASK(4,S_TC_VERD) -#define G_TC_VERD(x) _TC_GETVALUE(x,S_TC_VERD,M_TC_VERD) -#define V_TC_VERD(x) _TC_MAKEVALUE(x,S_TC_VERD) -#define SET_TC_VERD(v,n) ((V_TC_VERD(n)) | (v & ~M_TC_VERD)) - -#define S_TC_FROM _TC_MAKE32(6) -#define M_TC_FROM _TC_MAKEMASK(2,S_TC_FROM) -#define G_TC_FROM(x) _TC_GETVALUE(x,S_TC_FROM,M_TC_FROM) -#define V_TC_FROM(x) _TC_MAKEVALUE(x,S_TC_FROM) -#define SET_TC_FROM(v,n) ((V_TC_FROM(n)) | (v & ~M_TC_FROM)) -#define AT_STACK 0x0 -#define AT_INGRESS 0x1 -#define AT_EGRESS 0x2 - -#define TC_NCLS _TC_MAKEMASK1(8) -#define SET_TC_NCLS(v) ( TC_NCLS | (v & ~TC_NCLS)) -#define CLR_TC_NCLS(v) ( v & ~TC_NCLS) - -#define S_TC_RTTL _TC_MAKE32(9) -#define M_TC_RTTL _TC_MAKEMASK(3,S_TC_RTTL) -#define G_TC_RTTL(x) _TC_GETVALUE(x,S_TC_RTTL,M_TC_RTTL) -#define V_TC_RTTL(x) _TC_MAKEVALUE(x,S_TC_RTTL) -#define SET_TC_RTTL(v,n) ((V_TC_RTTL(n)) | (v & ~M_TC_RTTL)) - -#define S_TC_AT _TC_MAKE32(12) -#define M_TC_AT _TC_MAKEMASK(2,S_TC_AT) -#define G_TC_AT(x) _TC_GETVALUE(x,S_TC_AT,M_TC_AT) -#define V_TC_AT(x) _TC_MAKEVALUE(x,S_TC_AT) -#define SET_TC_AT(v,n) ((V_TC_AT(n)) | (v & ~M_TC_AT)) - -/* Action attributes */ -enum -{ - TCA_ACT_UNSPEC, - TCA_ACT_KIND, - TCA_ACT_OPTIONS, - TCA_ACT_INDEX, - TCA_ACT_STATS, - __TCA_ACT_MAX -}; - -#define TCA_ACT_MAX __TCA_ACT_MAX -#define TCA_OLD_COMPAT (TCA_ACT_MAX+1) -#define TCA_ACT_MAX_PRIO 32 -#define TCA_ACT_BIND 1 -#define TCA_ACT_NOBIND 0 -#define TCA_ACT_UNBIND 1 -#define TCA_ACT_NOUNBIND 0 -#define TCA_ACT_REPLACE 1 -#define TCA_ACT_NOREPLACE 0 -#define MAX_REC_LOOP 4 -#define MAX_RED_LOOP 4 - -#define TC_ACT_UNSPEC (-1) -#define TC_ACT_OK 0 -#define TC_ACT_RECLASSIFY 1 -#define TC_ACT_SHOT 2 -#define TC_ACT_PIPE 3 -#define TC_ACT_STOLEN 4 -#define TC_ACT_QUEUED 5 -#define TC_ACT_REPEAT 6 -#define TC_ACT_JUMP 0x10000000 - -/* Action type identifiers*/ -enum -{ - TCA_ID_UNSPEC=0, - TCA_ID_POLICE=1, - /* other actions go here */ - __TCA_ID_MAX=255 -}; - -#define TCA_ID_MAX __TCA_ID_MAX - -struct tc_police -{ - __u32 index; - int action; -#define TC_POLICE_UNSPEC TC_ACT_UNSPEC -#define TC_POLICE_OK TC_ACT_OK -#define TC_POLICE_RECLASSIFY TC_ACT_RECLASSIFY -#define TC_POLICE_SHOT TC_ACT_SHOT -#define TC_POLICE_PIPE TC_ACT_PIPE - - __u32 limit; - __u32 burst; - __u32 mtu; - struct tc_ratespec rate; - struct tc_ratespec peakrate; - int refcnt; - int bindcnt; - __u32 capab; -}; - -struct tcf_t -{ - __u64 install; - __u64 lastuse; - __u64 expires; -}; - -struct tc_cnt -{ - int refcnt; - int bindcnt; -}; - -#define tc_gen \ - __u32 index; \ - __u32 capab; \ - int action; \ - int refcnt; \ - int bindcnt - -enum -{ - TCA_POLICE_UNSPEC, - TCA_POLICE_TBF, - TCA_POLICE_RATE, - TCA_POLICE_PEAKRATE, - TCA_POLICE_AVRATE, - TCA_POLICE_RESULT, - __TCA_POLICE_MAX -#define TCA_POLICE_RESULT TCA_POLICE_RESULT -}; - -#define TCA_POLICE_MAX (__TCA_POLICE_MAX - 1) - -/* U32 filters */ - -#define TC_U32_HTID(h) ((h)&0xFFF00000) -#define TC_U32_USERHTID(h) (TC_U32_HTID(h)>>20) -#define TC_U32_HASH(h) (((h)>>12)&0xFF) -#define TC_U32_NODE(h) ((h)&0xFFF) -#define TC_U32_KEY(h) ((h)&0xFFFFF) -#define TC_U32_UNSPEC 0 -#define TC_U32_ROOT (0xFFF00000) - -enum -{ - TCA_U32_UNSPEC, - TCA_U32_CLASSID, - TCA_U32_HASH, - TCA_U32_LINK, - TCA_U32_DIVISOR, - TCA_U32_SEL, - TCA_U32_POLICE, - TCA_U32_ACT, - TCA_U32_INDEV, - TCA_U32_PCNT, - TCA_U32_MARK, - __TCA_U32_MAX -}; - -#define TCA_U32_MAX (__TCA_U32_MAX - 1) - -struct tc_u32_key -{ - __u32 mask; - __u32 val; - int off; - int offmask; -}; - -struct tc_u32_sel -{ - unsigned char flags; - unsigned char offshift; - unsigned char nkeys; - - __u16 offmask; - __u16 off; - short offoff; - - short hoff; - __u32 hmask; - struct tc_u32_key keys[0]; -}; - -struct tc_u32_mark -{ - __u32 val; - __u32 mask; - __u32 success; -}; - -struct tc_u32_pcnt -{ - __u64 rcnt; - __u64 rhit; - __u64 kcnts[0]; -}; - -/* Flags */ - -#define TC_U32_TERMINAL 1 -#define TC_U32_OFFSET 2 -#define TC_U32_VAROFFSET 4 -#define TC_U32_EAT 8 - -#define TC_U32_MAXDEPTH 8 - - -/* RSVP filter */ - -enum -{ - TCA_RSVP_UNSPEC, - TCA_RSVP_CLASSID, - TCA_RSVP_DST, - TCA_RSVP_SRC, - TCA_RSVP_PINFO, - TCA_RSVP_POLICE, - TCA_RSVP_ACT, - __TCA_RSVP_MAX -}; - -#define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1 ) - -struct tc_rsvp_gpi -{ - __u32 key; - __u32 mask; - int offset; -}; - -struct tc_rsvp_pinfo -{ - struct tc_rsvp_gpi dpi; - struct tc_rsvp_gpi spi; - __u8 protocol; - __u8 tunnelid; - __u8 tunnelhdr; - __u8 pad; -}; - -/* ROUTE filter */ - -enum -{ - TCA_ROUTE4_UNSPEC, - TCA_ROUTE4_CLASSID, - TCA_ROUTE4_TO, - TCA_ROUTE4_FROM, - TCA_ROUTE4_IIF, - TCA_ROUTE4_POLICE, - TCA_ROUTE4_ACT, - __TCA_ROUTE4_MAX -}; - -#define TCA_ROUTE4_MAX (__TCA_ROUTE4_MAX - 1) - - -/* FW filter */ - -enum -{ - TCA_FW_UNSPEC, - TCA_FW_CLASSID, - TCA_FW_POLICE, - TCA_FW_INDEV, /* used by CONFIG_NET_CLS_IND */ - TCA_FW_ACT, /* used by CONFIG_NET_CLS_ACT */ - __TCA_FW_MAX -}; - -#define TCA_FW_MAX (__TCA_FW_MAX - 1) - -/* TC index filter */ - -enum -{ - TCA_TCINDEX_UNSPEC, - TCA_TCINDEX_HASH, - TCA_TCINDEX_MASK, - TCA_TCINDEX_SHIFT, - TCA_TCINDEX_FALL_THROUGH, - TCA_TCINDEX_CLASSID, - TCA_TCINDEX_POLICE, - TCA_TCINDEX_ACT, - __TCA_TCINDEX_MAX -}; - -#define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1) - -/* Basic filter */ - -enum -{ - TCA_BASIC_UNSPEC, - TCA_BASIC_CLASSID, - TCA_BASIC_EMATCHES, - TCA_BASIC_ACT, - TCA_BASIC_POLICE, - __TCA_BASIC_MAX -}; - -#define TCA_BASIC_MAX (__TCA_BASIC_MAX - 1) - -/* Extended Matches */ - -struct tcf_ematch_tree_hdr -{ - __u16 nmatches; - __u16 progid; -}; - -enum -{ - TCA_EMATCH_TREE_UNSPEC, - TCA_EMATCH_TREE_HDR, - TCA_EMATCH_TREE_LIST, - __TCA_EMATCH_TREE_MAX -}; -#define TCA_EMATCH_TREE_MAX (__TCA_EMATCH_TREE_MAX - 1) - -struct tcf_ematch_hdr -{ - __u16 matchid; - __u16 kind; - __u16 flags; - __u16 pad; /* currently unused */ -}; - -/* 0 1 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - * +-----------------------+-+-+---+ - * | Unused |S|I| R | - * +-----------------------+-+-+---+ - * - * R(2) ::= relation to next ematch - * where: 0 0 END (last ematch) - * 0 1 AND - * 1 0 OR - * 1 1 Unused (invalid) - * I(1) ::= invert result - * S(1) ::= simple payload - */ -#define TCF_EM_REL_END 0 -#define TCF_EM_REL_AND (1<<0) -#define TCF_EM_REL_OR (1<<1) -#define TCF_EM_INVERT (1<<2) -#define TCF_EM_SIMPLE (1<<3) - -#define TCF_EM_REL_MASK 3 -#define TCF_EM_REL_VALID(v) (((v) & TCF_EM_REL_MASK) != TCF_EM_REL_MASK) - -enum -{ - TCF_LAYER_LINK, - TCF_LAYER_NETWORK, - TCF_LAYER_TRANSPORT, - __TCF_LAYER_MAX -}; -#define TCF_LAYER_MAX (__TCF_LAYER_MAX - 1) - -/* Ematch type assignments - * 1..32767 Reserved for ematches inside kernel tree - * 32768..65535 Free to use, not reliable - */ -enum -{ - TCF_EM_CONTAINER, - TCF_EM_CMP, - TCF_EM_NBYTE, - TCF_EM_U32, - TCF_EM_META, - TCF_EM_TEXT, - __TCF_EM_MAX -}; - -enum -{ - TCF_EM_PROG_TC -}; - -enum -{ - TCF_EM_OPND_EQ, - TCF_EM_OPND_GT, - TCF_EM_OPND_LT -}; - -#endif diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h deleted file mode 100644 index d10f353..0000000 --- a/include/linux/pkt_sched.h +++ /dev/null @@ -1,469 +0,0 @@ -#ifndef __LINUX_PKT_SCHED_H -#define __LINUX_PKT_SCHED_H - -/* Logical priority bands not depending on specific packet scheduler. - Every scheduler will map them to real traffic classes, if it has - no more precise mechanism to classify packets. - - These numbers have no special meaning, though their coincidence - with obsolete IPv6 values is not occasional :-). New IPv6 drafts - preferred full anarchy inspired by diffserv group. - - Note: TC_PRIO_BESTEFFORT does not mean that it is the most unhappy - class, actually, as rule it will be handled with more care than - filler or even bulk. - */ - -#define TC_PRIO_BESTEFFORT 0 -#define TC_PRIO_FILLER 1 -#define TC_PRIO_BULK 2 -#define TC_PRIO_INTERACTIVE_BULK 4 -#define TC_PRIO_INTERACTIVE 6 -#define TC_PRIO_CONTROL 7 - -#define TC_PRIO_MAX 15 - -/* Generic queue statistics, available for all the elements. - Particular schedulers may have also their private records. - */ - -struct tc_stats -{ - __u64 bytes; /* NUmber of enqueues bytes */ - __u32 packets; /* Number of enqueued packets */ - __u32 drops; /* Packets dropped because of lack of resources */ - __u32 overlimits; /* Number of throttle events when this - * flow goes out of allocated bandwidth */ - __u32 bps; /* Current flow byte rate */ - __u32 pps; /* Current flow packet rate */ - __u32 qlen; - __u32 backlog; -}; - -struct tc_estimator -{ - signed char interval; - unsigned char ewma_log; -}; - -/* "Handles" - --------- - - All the traffic control objects have 32bit identifiers, or "handles". - - They can be considered as opaque numbers from user API viewpoint, - but actually they always consist of two fields: major and - minor numbers, which are interpreted by kernel specially, - that may be used by applications, though not recommended. - - F.e. qdisc handles always have minor number equal to zero, - classes (or flows) have major equal to parent qdisc major, and - minor uniquely identifying class inside qdisc. - - Macros to manipulate handles: - */ - -#define TC_H_MAJ_MASK (0xFFFF0000U) -#define TC_H_MIN_MASK (0x0000FFFFU) -#define TC_H_MAJ(h) ((h)&TC_H_MAJ_MASK) -#define TC_H_MIN(h) ((h)&TC_H_MIN_MASK) -#define TC_H_MAKE(maj,min) (((maj)&TC_H_MAJ_MASK)|((min)&TC_H_MIN_MASK)) - -#define TC_H_UNSPEC (0U) -#define TC_H_ROOT (0xFFFFFFFFU) -#define TC_H_INGRESS (0xFFFFFFF1U) - -struct tc_ratespec -{ - unsigned char cell_log; - unsigned char __reserved; - unsigned short feature; - short addend; - unsigned short mpu; - __u32 rate; -}; - -/* FIFO section */ - -struct tc_fifo_qopt -{ - __u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */ -}; - -/* PRIO section */ - -#define TCQ_PRIO_BANDS 16 -#define TCQ_MIN_PRIO_BANDS 2 - -struct tc_prio_qopt -{ - int bands; /* Number of bands */ - __u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */ -}; - -/* TBF section */ - -struct tc_tbf_qopt -{ - struct tc_ratespec rate; - struct tc_ratespec peakrate; - __u32 limit; - __u32 buffer; - __u32 mtu; -}; - -enum -{ - TCA_TBF_UNSPEC, - TCA_TBF_PARMS, - TCA_TBF_RTAB, - TCA_TBF_PTAB, - __TCA_TBF_MAX, -}; - -#define TCA_TBF_MAX (__TCA_TBF_MAX - 1) - - -/* TEQL section */ - -/* TEQL does not require any parameters */ - -/* SFQ section */ - -struct tc_sfq_qopt -{ - unsigned quantum; /* Bytes per round allocated to flow */ - int perturb_period; /* Period of hash perturbation */ - __u32 limit; /* Maximal packets in queue */ - unsigned divisor; /* Hash divisor */ - unsigned flows; /* Maximal number of flows */ -}; - -/* - * NOTE: limit, divisor and flows are hardwired to code at the moment. - * - * limit=flows=128, divisor=1024; - * - * The only reason for this is efficiency, it is possible - * to change these parameters in compile time. - */ - -/* RED section */ - -enum -{ - TCA_RED_UNSPEC, - TCA_RED_PARMS, - TCA_RED_STAB, - __TCA_RED_MAX, -}; - -#define TCA_RED_MAX (__TCA_RED_MAX - 1) - -struct tc_red_qopt -{ - __u32 limit; /* HARD maximal queue length (bytes) */ - __u32 qth_min; /* Min average length threshold (bytes) */ - __u32 qth_max; /* Max average length threshold (bytes) */ - unsigned char Wlog; /* log(W) */ - unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */ - unsigned char Scell_log; /* cell size for idle damping */ - unsigned char flags; -#define TC_RED_ECN 1 -#define TC_RED_HARDDROP 2 -}; - -struct tc_red_xstats -{ - __u32 early; /* Early drops */ - __u32 pdrop; /* Drops due to queue limits */ - __u32 other; /* Drops due to drop() calls */ - __u32 marked; /* Marked packets */ -}; - -/* GRED section */ - -#define MAX_DPs 16 - -enum -{ - TCA_GRED_UNSPEC, - TCA_GRED_PARMS, - TCA_GRED_STAB, - TCA_GRED_DPS, - __TCA_GRED_MAX, -}; - -#define TCA_GRED_MAX (__TCA_GRED_MAX - 1) - -struct tc_gred_qopt -{ - __u32 limit; /* HARD maximal queue length (bytes) */ - __u32 qth_min; /* Min average length threshold (bytes) */ - __u32 qth_max; /* Max average length threshold (bytes) */ - __u32 DP; /* upto 2^32 DPs */ - __u32 backlog; - __u32 qave; - __u32 forced; - __u32 early; - __u32 other; - __u32 pdrop; - __u8 Wlog; /* log(W) */ - __u8 Plog; /* log(P_max/(qth_max-qth_min)) */ - __u8 Scell_log; /* cell size for idle damping */ - __u8 prio; /* prio of this VQ */ - __u32 packets; - __u32 bytesin; -}; - -/* gred setup */ -struct tc_gred_sopt -{ - __u32 DPs; - __u32 def_DP; - __u8 grio; - __u8 flags; - __u16 pad1; -}; - -/* HTB section */ -#define TC_HTB_NUMPRIO 8 -#define TC_HTB_MAXDEPTH 8 -#define TC_HTB_PROTOVER 3 /* the same as HTB and TC's major */ - -struct tc_htb_opt -{ - struct tc_ratespec rate; - struct tc_ratespec ceil; - __u32 buffer; - __u32 cbuffer; - __u32 quantum; - __u32 level; /* out only */ - __u32 prio; -}; -struct tc_htb_glob -{ - __u32 version; /* to match HTB/TC */ - __u32 rate2quantum; /* bps->quantum divisor */ - __u32 defcls; /* default class number */ - __u32 debug; /* debug flags */ - - /* stats */ - __u32 direct_pkts; /* count of non shapped packets */ -}; -enum -{ - TCA_HTB_UNSPEC, - TCA_HTB_PARMS, - TCA_HTB_INIT, - TCA_HTB_CTAB, - TCA_HTB_RTAB, - __TCA_HTB_MAX, -}; - -#define TCA_HTB_MAX (__TCA_HTB_MAX - 1) - -struct tc_htb_xstats -{ - __u32 lends; - __u32 borrows; - __u32 giants; /* too big packets (rate will not be accurate) */ - __u32 tokens; - __u32 ctokens; -}; - -/* HFSC section */ - -struct tc_hfsc_qopt -{ - __u16 defcls; /* default class */ -}; - -struct tc_service_curve -{ - __u32 m1; /* slope of the first segment in bps */ - __u32 d; /* x-projection of the first segment in us */ - __u32 m2; /* slope of the second segment in bps */ -}; - -struct tc_hfsc_stats -{ - __u64 work; /* total work done */ - __u64 rtwork; /* work done by real-time criteria */ - __u32 period; /* current period */ - __u32 level; /* class level in hierarchy */ -}; - -enum -{ - TCA_HFSC_UNSPEC, - TCA_HFSC_RSC, - TCA_HFSC_FSC, - TCA_HFSC_USC, - __TCA_HFSC_MAX, -}; - -#define TCA_HFSC_MAX (__TCA_HFSC_MAX - 1) - - -/* CBQ section */ - -#define TC_CBQ_MAXPRIO 8 -#define TC_CBQ_MAXLEVEL 8 -#define TC_CBQ_DEF_EWMA 5 - -struct tc_cbq_lssopt -{ - unsigned char change; - unsigned char flags; -#define TCF_CBQ_LSS_BOUNDED 1 -#define TCF_CBQ_LSS_ISOLATED 2 - unsigned char ewma_log; - unsigned char level; -#define TCF_CBQ_LSS_FLAGS 1 -#define TCF_CBQ_LSS_EWMA 2 -#define TCF_CBQ_LSS_MAXIDLE 4 -#define TCF_CBQ_LSS_MINIDLE 8 -#define TCF_CBQ_LSS_OFFTIME 0x10 -#define TCF_CBQ_LSS_AVPKT 0x20 - __u32 maxidle; - __u32 minidle; - __u32 offtime; - __u32 avpkt; -}; - -struct tc_cbq_wrropt -{ - unsigned char flags; - unsigned char priority; - unsigned char cpriority; - unsigned char __reserved; - __u32 allot; - __u32 weight; -}; - -struct tc_cbq_ovl -{ - unsigned char strategy; -#define TC_CBQ_OVL_CLASSIC 0 -#define TC_CBQ_OVL_DELAY 1 -#define TC_CBQ_OVL_LOWPRIO 2 -#define TC_CBQ_OVL_DROP 3 -#define TC_CBQ_OVL_RCLASSIC 4 - unsigned char priority2; - __u16 pad; - __u32 penalty; -}; - -struct tc_cbq_police -{ - unsigned char police; - unsigned char __res1; - unsigned short __res2; -}; - -struct tc_cbq_fopt -{ - __u32 split; - __u32 defmap; - __u32 defchange; -}; - -struct tc_cbq_xstats -{ - __u32 borrows; - __u32 overactions; - __s32 avgidle; - __s32 undertime; -}; - -enum -{ - TCA_CBQ_UNSPEC, - TCA_CBQ_LSSOPT, - TCA_CBQ_WRROPT, - TCA_CBQ_FOPT, - TCA_CBQ_OVL_STRATEGY, - TCA_CBQ_RATE, - TCA_CBQ_RTAB, - TCA_CBQ_POLICE, - __TCA_CBQ_MAX, -}; - -#define TCA_CBQ_MAX (__TCA_CBQ_MAX - 1) - -/* dsmark section */ - -enum { - TCA_DSMARK_UNSPEC, - TCA_DSMARK_INDICES, - TCA_DSMARK_DEFAULT_INDEX, - TCA_DSMARK_SET_TC_INDEX, - TCA_DSMARK_MASK, - TCA_DSMARK_VALUE, - __TCA_DSMARK_MAX, -}; - -#define TCA_DSMARK_MAX (__TCA_DSMARK_MAX - 1) - -/* ATM section */ - -enum { - TCA_ATM_UNSPEC, - TCA_ATM_FD, /* file/socket descriptor */ - TCA_ATM_PTR, /* pointer to descriptor - later */ - TCA_ATM_HDR, /* LL header */ - TCA_ATM_EXCESS, /* excess traffic class (0 for CLP) */ - TCA_ATM_ADDR, /* PVC address (for output only) */ - TCA_ATM_STATE, /* VC state (ATM_VS_*; for output only) */ - __TCA_ATM_MAX, -}; - -#define TCA_ATM_MAX (__TCA_ATM_MAX - 1) - -/* Network emulator */ - -enum -{ - TCA_NETEM_UNSPEC, - TCA_NETEM_CORR, - TCA_NETEM_DELAY_DIST, - TCA_NETEM_REORDER, - TCA_NETEM_CORRUPT, - __TCA_NETEM_MAX, -}; - -#define TCA_NETEM_MAX (__TCA_NETEM_MAX - 1) - -struct tc_netem_qopt -{ - __u32 latency; /* added delay (us) */ - __u32 limit; /* fifo limit (packets) */ - __u32 loss; /* random packet loss (0=none ~0=100%) */ - __u32 gap; /* re-ordering gap (0 for none) */ - __u32 duplicate; /* random packet dup (0=none ~0=100%) */ - __u32 jitter; /* random jitter in latency (us) */ -}; - -struct tc_netem_corr -{ - __u32 delay_corr; /* delay correlation */ - __u32 loss_corr; /* packet loss correlation */ - __u32 dup_corr; /* duplicate correlation */ -}; - -struct tc_netem_reorder -{ - __u32 probability; - __u32 correlation; -}; - -struct tc_netem_corrupt -{ - __u32 probability; - __u32 correlation; -}; - -#define NETEM_DIST_SCALE 8192 - -#endif diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h deleted file mode 100644 index 7504618..0000000 --- a/include/linux/rtnetlink.h +++ /dev/null @@ -1,906 +0,0 @@ -#ifndef __LINUX_RTNETLINK_H -#define __LINUX_RTNETLINK_H - -#include <linux/netlink.h> - -/**** - * Routing/neighbour discovery messages. - ****/ - -/* Types of messages */ - -enum { - RTM_BASE = 16, -#define RTM_BASE RTM_BASE - - RTM_NEWLINK = 16, -#define RTM_NEWLINK RTM_NEWLINK - RTM_DELLINK, -#define RTM_DELLINK RTM_DELLINK - RTM_GETLINK, -#define RTM_GETLINK RTM_GETLINK - RTM_SETLINK, -#define RTM_SETLINK RTM_SETLINK - - RTM_NEWADDR = 20, -#define RTM_NEWADDR RTM_NEWADDR - RTM_DELADDR, -#define RTM_DELADDR RTM_DELADDR - RTM_GETADDR, -#define RTM_GETADDR RTM_GETADDR - - RTM_NEWROUTE = 24, -#define RTM_NEWROUTE RTM_NEWROUTE - RTM_DELROUTE, -#define RTM_DELROUTE RTM_DELROUTE - RTM_GETROUTE, -#define RTM_GETROUTE RTM_GETROUTE - - RTM_NEWNEIGH = 28, -#define RTM_NEWNEIGH RTM_NEWNEIGH - RTM_DELNEIGH, -#define RTM_DELNEIGH RTM_DELNEIGH - RTM_GETNEIGH, -#define RTM_GETNEIGH RTM_GETNEIGH - - RTM_NEWRULE = 32, -#define RTM_NEWRULE RTM_NEWRULE - RTM_DELRULE, -#define RTM_DELRULE RTM_DELRULE - RTM_GETRULE, -#define RTM_GETRULE RTM_GETRULE - - RTM_NEWQDISC = 36, -#define RTM_NEWQDISC RTM_NEWQDISC - RTM_DELQDISC, -#define RTM_DELQDISC RTM_DELQDISC - RTM_GETQDISC, -#define RTM_GETQDISC RTM_GETQDISC - - RTM_NEWTCLASS = 40, -#define RTM_NEWTCLASS RTM_NEWTCLASS - RTM_DELTCLASS, -#define RTM_DELTCLASS RTM_DELTCLASS - RTM_GETTCLASS, -#define RTM_GETTCLASS RTM_GETTCLASS - - RTM_NEWTFILTER = 44, -#define RTM_NEWTFILTER RTM_NEWTFILTER - RTM_DELTFILTER, -#define RTM_DELTFILTER RTM_DELTFILTER - RTM_GETTFILTER, -#define RTM_GETTFILTER RTM_GETTFILTER - - RTM_NEWACTION = 48, -#define RTM_NEWACTION RTM_NEWACTION - RTM_DELACTION, -#define RTM_DELACTION RTM_DELACTION - RTM_GETACTION, -#define RTM_GETACTION RTM_GETACTION - - RTM_NEWPREFIX = 52, -#define RTM_NEWPREFIX RTM_NEWPREFIX - RTM_GETPREFIX = 54, -#define RTM_GETPREFIX RTM_GETPREFIX - - RTM_GETMULTICAST = 58, -#define RTM_GETMULTICAST RTM_GETMULTICAST - - RTM_GETANYCAST = 62, -#define RTM_GETANYCAST RTM_GETANYCAST - - RTM_NEWNEIGHTBL = 64, -#define RTM_NEWNEIGHTBL RTM_NEWNEIGHTBL - RTM_GETNEIGHTBL = 66, -#define RTM_GETNEIGHTBL RTM_GETNEIGHTBL - RTM_SETNEIGHTBL, -#define RTM_SETNEIGHTBL RTM_SETNEIGHTBL - - __RTM_MAX, -#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) -}; - -#define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE) -#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2) -#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2) - -/* - Generic structure for encapsulation of optional route information. - It is reminiscent of sockaddr, but with sa_family replaced - with attribute type. - */ - -struct rtattr -{ - unsigned short rta_len; - unsigned short rta_type; -}; - -/* Macros to handle rtattributes */ - -#define RTA_ALIGNTO 4 -#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) ) -#define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \ - (rta)->rta_len >= sizeof(struct rtattr) && \ - (rta)->rta_len <= (len)) -#define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), \ - (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len))) -#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len)) -#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len)) -#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0))) -#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) - - - - -/****************************************************************************** - * Definitions used in routing table administration. - ****/ - -struct rtmsg -{ - unsigned char rtm_family; - unsigned char rtm_dst_len; - unsigned char rtm_src_len; - unsigned char rtm_tos; - - unsigned char rtm_table; /* Routing table id */ - unsigned char rtm_protocol; /* Routing protocol; see below */ - unsigned char rtm_scope; /* See below */ - unsigned char rtm_type; /* See below */ - - unsigned rtm_flags; -}; - -/* rtm_type */ - -enum -{ - RTN_UNSPEC, - RTN_UNICAST, /* Gateway or direct route */ - RTN_LOCAL, /* Accept locally */ - RTN_BROADCAST, /* Accept locally as broadcast, - send as broadcast */ - RTN_ANYCAST, /* Accept locally as broadcast, - but send as unicast */ - RTN_MULTICAST, /* Multicast route */ - RTN_BLACKHOLE, /* Drop */ - RTN_UNREACHABLE, /* Destination is unreachable */ - RTN_PROHIBIT, /* Administratively prohibited */ - RTN_THROW, /* Not in this table */ - RTN_NAT, /* Translate this address */ - RTN_XRESOLVE, /* Use external resolver */ - __RTN_MAX -}; - -#define RTN_MAX (__RTN_MAX - 1) - - -/* rtm_protocol */ - -#define RTPROT_UNSPEC 0 -#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects; - not used by current IPv4 */ -#define RTPROT_KERNEL 2 /* Route installed by kernel */ -#define RTPROT_BOOT 3 /* Route installed during boot */ -#define RTPROT_STATIC 4 /* Route installed by administrator */ - -/* Values of protocol >= RTPROT_STATIC are not interpreted by kernel; - they are just passed from user and back as is. - It will be used by hypothetical multiple routing daemons. - Note that protocol values should be standardized in order to - avoid conflicts. - */ - -#define RTPROT_GATED 8 /* Apparently, GateD */ -#define RTPROT_RA 9 /* RDISC/ND router advertisements */ -#define RTPROT_MRT 10 /* Merit MRT */ -#define RTPROT_ZEBRA 11 /* Zebra */ -#define RTPROT_BIRD 12 /* BIRD */ -#define RTPROT_DNROUTED 13 /* DECnet routing daemon */ -#define RTPROT_XORP 14 /* XORP */ -#define RTPROT_NTK 15 /* Netsukuku */ - -/* rtm_scope - - Really it is not scope, but sort of distance to the destination. - NOWHERE are reserved for not existing destinations, HOST is our - local addresses, LINK are destinations, located on directly attached - link and UNIVERSE is everywhere in the Universe. - - Intermediate values are also possible f.e. interior routes - could be assigned a value between UNIVERSE and LINK. -*/ - -enum rt_scope_t -{ - RT_SCOPE_UNIVERSE=0, -/* User defined values */ - RT_SCOPE_SITE=200, - RT_SCOPE_LINK=253, - RT_SCOPE_HOST=254, - RT_SCOPE_NOWHERE=255 -}; - -/* rtm_flags */ - -#define RTM_F_NOTIFY 0x100 /* Notify user of route change */ -#define RTM_F_CLONED 0x200 /* This route is cloned */ -#define RTM_F_EQUALIZE 0x400 /* Multipath equalizer: NI */ -#define RTM_F_PREFIX 0x800 /* Prefix addresses */ - -/* Reserved table identifiers */ - -enum rt_class_t -{ - RT_TABLE_UNSPEC=0, -/* User defined values */ - RT_TABLE_DEFAULT=253, - RT_TABLE_MAIN=254, - RT_TABLE_LOCAL=255, - __RT_TABLE_MAX -}; -#define RT_TABLE_MAX (__RT_TABLE_MAX - 1) - - - -/* Routing message attributes */ - -enum rtattr_type_t -{ - RTA_UNSPEC, - RTA_DST, - RTA_SRC, - RTA_IIF, - RTA_OIF, - RTA_GATEWAY, - RTA_PRIORITY, - RTA_PREFSRC, - RTA_METRICS, - RTA_MULTIPATH, - RTA_PROTOINFO, - RTA_FLOW, - RTA_CACHEINFO, - RTA_SESSION, - RTA_MP_ALGO, - __RTA_MAX -}; - -#define RTA_MAX (__RTA_MAX - 1) - -#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg)))) -#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg)) - -/* RTM_MULTIPATH --- array of struct rtnexthop. - * - * "struct rtnexthop" describes all necessary nexthop information, - * i.e. parameters of path to a destination via this nexthop. - * - * At the moment it is impossible to set different prefsrc, mtu, window - * and rtt for different paths from multipath. - */ - -struct rtnexthop -{ - unsigned short rtnh_len; - unsigned char rtnh_flags; - unsigned char rtnh_hops; - int rtnh_ifindex; -}; - -/* rtnh_flags */ - -#define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */ -#define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */ -#define RTNH_F_ONLINK 4 /* Gateway is forced on link */ - -/* Macros to handle hexthops */ - -#define RTNH_ALIGNTO 4 -#define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) ) -#define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \ - ((int)(rtnh)->rtnh_len) <= (len)) -#define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len))) -#define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len)) -#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len)) -#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0))) - -/* RTM_CACHEINFO */ - -struct rta_cacheinfo -{ - __u32 rta_clntref; - __u32 rta_lastuse; - __s32 rta_expires; - __u32 rta_error; - __u32 rta_used; - -#define RTNETLINK_HAVE_PEERINFO 1 - __u32 rta_id; - __u32 rta_ts; - __u32 rta_tsage; -}; - -/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */ - -enum -{ - RTAX_UNSPEC, -#define RTAX_UNSPEC RTAX_UNSPEC - RTAX_LOCK, -#define RTAX_LOCK RTAX_LOCK - RTAX_MTU, -#define RTAX_MTU RTAX_MTU - RTAX_WINDOW, -#define RTAX_WINDOW RTAX_WINDOW - RTAX_RTT, -#define RTAX_RTT RTAX_RTT - RTAX_RTTVAR, -#define RTAX_RTTVAR RTAX_RTTVAR - RTAX_SSTHRESH, -#define RTAX_SSTHRESH RTAX_SSTHRESH - RTAX_CWND, -#define RTAX_CWND RTAX_CWND - RTAX_ADVMSS, -#define RTAX_ADVMSS RTAX_ADVMSS - RTAX_REORDERING, -#define RTAX_REORDERING RTAX_REORDERING - RTAX_HOPLIMIT, -#define RTAX_HOPLIMIT RTAX_HOPLIMIT - RTAX_INITCWND, -#define RTAX_INITCWND RTAX_INITCWND - RTAX_FEATURES, -#define RTAX_FEATURES RTAX_FEATURES - __RTAX_MAX -}; - -#define RTAX_MAX (__RTAX_MAX - 1) - -#define RTAX_FEATURE_ECN 0x00000001 -#define RTAX_FEATURE_SACK 0x00000002 -#define RTAX_FEATURE_TIMESTAMP 0x00000004 -#define RTAX_FEATURE_ALLFRAG 0x00000008 - -struct rta_session -{ - __u8 proto; - __u8 pad1; - __u16 pad2; - - union { - struct { - __u16 sport; - __u16 dport; - } ports; - - struct { - __u8 type; - __u8 code; - __u16 ident; - } icmpt; - - __u32 spi; - } u; -}; - - -/********************************************************* - * Interface address. - ****/ - -struct ifaddrmsg -{ - unsigned char ifa_family; - unsigned char ifa_prefixlen; /* The prefix length */ - unsigned char ifa_flags; /* Flags */ - unsigned char ifa_scope; /* See above */ - int ifa_index; /* Link index */ -}; - -enum -{ - IFA_UNSPEC, - IFA_ADDRESS, - IFA_LOCAL, - IFA_LABEL, - IFA_BROADCAST, - IFA_ANYCAST, - IFA_CACHEINFO, - IFA_MULTICAST, - __IFA_MAX -}; - -#define IFA_MAX (__IFA_MAX - 1) - -/* ifa_flags */ - -#define IFA_F_SECONDARY 0x01 -#define IFA_F_TEMPORARY IFA_F_SECONDARY - -#define IFA_F_DEPRECATED 0x20 -#define IFA_F_TENTATIVE 0x40 -#define IFA_F_PERMANENT 0x80 - -struct ifa_cacheinfo -{ - __u32 ifa_prefered; - __u32 ifa_valid; - __u32 cstamp; /* created timestamp, hundredths of seconds */ - __u32 tstamp; /* updated timestamp, hundredths of seconds */ -}; - - -#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)))) -#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg)) - -/* - Important comment: - IFA_ADDRESS is prefix address, rather than local interface address. - It makes no difference for normally configured broadcast interfaces, - but for point-to-point IFA_ADDRESS is DESTINATION address, - local address is supplied in IFA_LOCAL attribute. - */ - -/************************************************************** - * Neighbour discovery. - ****/ - -struct ndmsg -{ - unsigned char ndm_family; - unsigned char ndm_pad1; - unsigned short ndm_pad2; - int ndm_ifindex; /* Link index */ - __u16 ndm_state; - __u8 ndm_flags; - __u8 ndm_type; -}; - -enum -{ - NDA_UNSPEC, - NDA_DST, - NDA_LLADDR, - NDA_CACHEINFO, - NDA_PROBES, - __NDA_MAX -}; - -#define NDA_MAX (__NDA_MAX - 1) - -#define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) -#define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg)) - -/* - * Neighbor Cache Entry Flags - */ - -#define NTF_PROXY 0x08 /* == ATF_PUBL */ -#define NTF_ROUTER 0x80 - -/* - * Neighbor Cache Entry States. - */ - -#define NUD_INCOMPLETE 0x01 -#define NUD_REACHABLE 0x02 -#define NUD_STALE 0x04 -#define NUD_DELAY 0x08 -#define NUD_PROBE 0x10 -#define NUD_FAILED 0x20 - -/* Dummy states */ -#define NUD_NOARP 0x40 -#define NUD_PERMANENT 0x80 -#define NUD_NONE 0x00 - - -struct nda_cacheinfo -{ - __u32 ndm_confirmed; - __u32 ndm_used; - __u32 ndm_updated; - __u32 ndm_refcnt; -}; - - -/***************************************************************** - * Neighbour tables specific messages. - * - * To retrieve the neighbour tables send RTM_GETNEIGHTBL with the - * NLM_F_DUMP flag set. Every neighbour table configuration is - * spread over multiple messages to avoid running into message - * size limits on systems with many interfaces. The first message - * in the sequence transports all not device specific data such as - * statistics, configuration, and the default parameter set. - * This message is followed by 0..n messages carrying device - * specific parameter sets. - * Although the ordering should be sufficient, NDTA_NAME can be - * used to identify sequences. The initial message can be identified - * by checking for NDTA_CONFIG. The device specific messages do - * not contain this TLV but have NDTPA_IFINDEX set to the - * corresponding interface index. - * - * To change neighbour table attributes, send RTM_SETNEIGHTBL - * with NDTA_NAME set. Changeable attribute include NDTA_THRESH[1-3], - * NDTA_GC_INTERVAL, and all TLVs in NDTA_PARMS unless marked - * otherwise. Device specific parameter sets can be changed by - * setting NDTPA_IFINDEX to the interface index of the corresponding - * device. - ****/ - -struct ndt_stats -{ - __u64 ndts_allocs; - __u64 ndts_destroys; - __u64 ndts_hash_grows; - __u64 ndts_res_failed; - __u64 ndts_lookups; - __u64 ndts_hits; - __u64 ndts_rcv_probes_mcast; - __u64 ndts_rcv_probes_ucast; - __u64 ndts_periodic_gc_runs; - __u64 ndts_forced_gc_runs; -}; - -enum { - NDTPA_UNSPEC, - NDTPA_IFINDEX, /* u32, unchangeable */ - NDTPA_REFCNT, /* u32, read-only */ - NDTPA_REACHABLE_TIME, /* u64, read-only, msecs */ - NDTPA_BASE_REACHABLE_TIME, /* u64, msecs */ - NDTPA_RETRANS_TIME, /* u64, msecs */ - NDTPA_GC_STALETIME, /* u64, msecs */ - NDTPA_DELAY_PROBE_TIME, /* u64, msecs */ - NDTPA_QUEUE_LEN, /* u32 */ - NDTPA_APP_PROBES, /* u32 */ - NDTPA_UCAST_PROBES, /* u32 */ - NDTPA_MCAST_PROBES, /* u32 */ - NDTPA_ANYCAST_DELAY, /* u64, msecs */ - NDTPA_PROXY_DELAY, /* u64, msecs */ - NDTPA_PROXY_QLEN, /* u32 */ - NDTPA_LOCKTIME, /* u64, msecs */ - __NDTPA_MAX -}; -#define NDTPA_MAX (__NDTPA_MAX - 1) - -struct ndtmsg -{ - __u8 ndtm_family; - __u8 ndtm_pad1; - __u16 ndtm_pad2; -}; - -struct ndt_config -{ - __u16 ndtc_key_len; - __u16 ndtc_entry_size; - __u32 ndtc_entries; - __u32 ndtc_last_flush; /* delta to now in msecs */ - __u32 ndtc_last_rand; /* delta to now in msecs */ - __u32 ndtc_hash_rnd; - __u32 ndtc_hash_mask; - __u32 ndtc_hash_chain_gc; - __u32 ndtc_proxy_qlen; -}; - -enum { - NDTA_UNSPEC, - NDTA_NAME, /* char *, unchangeable */ - NDTA_THRESH1, /* u32 */ - NDTA_THRESH2, /* u32 */ - NDTA_THRESH3, /* u32 */ - NDTA_CONFIG, /* struct ndt_config, read-only */ - NDTA_PARMS, /* nested TLV NDTPA_* */ - NDTA_STATS, /* struct ndt_stats, read-only */ - NDTA_GC_INTERVAL, /* u64, msecs */ - __NDTA_MAX -}; -#define NDTA_MAX (__NDTA_MAX - 1) - -#define NDTA_RTA(r) ((struct rtattr*)(((char*)(r)) + \ - NLMSG_ALIGN(sizeof(struct ndtmsg)))) -#define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndtmsg)) - - -/**** - * General form of address family dependent message. - ****/ - -struct rtgenmsg -{ - unsigned char rtgen_family; -}; - -/***************************************************************** - * Link layer specific messages. - ****/ - -/* struct ifinfomsg - * passes link level specific information, not dependent - * on network protocol. - */ - -struct ifinfomsg -{ - unsigned char ifi_family; - unsigned char __ifi_pad; - unsigned short ifi_type; /* ARPHRD_* */ - int ifi_index; /* Link index */ - unsigned ifi_flags; /* IFF_* flags */ - unsigned ifi_change; /* IFF_* change mask */ -}; - -/******************************************************************** - * prefix information - ****/ - -struct prefixmsg -{ - unsigned char prefix_family; - unsigned char prefix_pad1; - unsigned short prefix_pad2; - int prefix_ifindex; - unsigned char prefix_type; - unsigned char prefix_len; - unsigned char prefix_flags; - unsigned char prefix_pad3; -}; - -enum -{ - PREFIX_UNSPEC, - PREFIX_ADDRESS, - PREFIX_CACHEINFO, - __PREFIX_MAX -}; - -#define PREFIX_MAX (__PREFIX_MAX - 1) - -struct prefix_cacheinfo -{ - __u32 preferred_time; - __u32 valid_time; -}; - -/* The struct should be in sync with struct net_device_stats */ -struct rtnl_link_stats -{ - __u32 rx_packets; /* total packets received */ - __u32 tx_packets; /* total packets transmitted */ - __u32 rx_bytes; /* total bytes received */ - __u32 tx_bytes; /* total bytes transmitted */ - __u32 rx_errors; /* bad packets received */ - __u32 tx_errors; /* packet transmit problems */ - __u32 rx_dropped; /* no space in linux buffers */ - __u32 tx_dropped; /* no space available in linux */ - __u32 multicast; /* multicast packets received */ - __u32 collisions; - - /* detailed rx_errors: */ - __u32 rx_length_errors; - __u32 rx_over_errors; /* receiver ring buff overflow */ - __u32 rx_crc_errors; /* recved pkt with crc error */ - __u32 rx_frame_errors; /* recv'd frame alignment error */ - __u32 rx_fifo_errors; /* recv'r fifo overrun */ - __u32 rx_missed_errors; /* receiver missed packet */ - - /* detailed tx_errors */ - __u32 tx_aborted_errors; - __u32 tx_carrier_errors; - __u32 tx_fifo_errors; - __u32 tx_heartbeat_errors; - __u32 tx_window_errors; - - /* for cslip etc */ - __u32 rx_compressed; - __u32 tx_compressed; -}; - -/* The struct should be in sync with struct ifmap */ -struct rtnl_link_ifmap -{ - __u64 mem_start; - __u64 mem_end; - __u64 base_addr; - __u16 irq; - __u8 dma; - __u8 port; -}; - -enum -{ - IFLA_UNSPEC, - IFLA_ADDRESS, - IFLA_BROADCAST, - IFLA_IFNAME, - IFLA_MTU, - IFLA_LINK, - IFLA_QDISC, - IFLA_STATS, - IFLA_COST, -#define IFLA_COST IFLA_COST - IFLA_PRIORITY, -#define IFLA_PRIORITY IFLA_PRIORITY - IFLA_MASTER, -#define IFLA_MASTER IFLA_MASTER - IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */ -#define IFLA_WIRELESS IFLA_WIRELESS - IFLA_PROTINFO, /* Protocol specific information for a link */ -#define IFLA_PROTINFO IFLA_PROTINFO - IFLA_TXQLEN, -#define IFLA_TXQLEN IFLA_TXQLEN - IFLA_MAP, -#define IFLA_MAP IFLA_MAP - IFLA_WEIGHT, -#define IFLA_WEIGHT IFLA_WEIGHT - __IFLA_MAX -}; - - -#define IFLA_MAX (__IFLA_MAX - 1) - -#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) -#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) - -/* ifi_flags. - - IFF_* flags. - - The only change is: - IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are - more not changeable by user. They describe link media - characteristics and set by device driver. - - Comments: - - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid - - If neither of these three flags are set; - the interface is NBMA. - - - IFF_MULTICAST does not mean anything special: - multicasts can be used on all not-NBMA links. - IFF_MULTICAST means that this media uses special encapsulation - for multicast frames. Apparently, all IFF_POINTOPOINT and - IFF_BROADCAST devices are able to use multicasts too. - */ - -/* IFLA_LINK. - For usual devices it is equal ifi_index. - If it is a "virtual interface" (f.e. tunnel), ifi_link - can point to real physical interface (f.e. for bandwidth calculations), - or maybe 0, what means, that real media is unknown (usual - for IPIP tunnels, when route to endpoint is allowed to change) - */ - -/* Subtype attributes for IFLA_PROTINFO */ -enum -{ - IFLA_INET6_UNSPEC, - IFLA_INET6_FLAGS, /* link flags */ - IFLA_INET6_CONF, /* sysctl parameters */ - IFLA_INET6_STATS, /* statistics */ - IFLA_INET6_MCAST, /* MC things. What of them? */ - IFLA_INET6_CACHEINFO, /* time values and max reasm size */ - __IFLA_INET6_MAX -}; - -#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1) - -struct ifla_cacheinfo -{ - __u32 max_reasm_len; - __u32 tstamp; /* ipv6InterfaceTable updated timestamp */ - __u32 reachable_time; - __u32 retrans_time; -}; - -/***************************************************************** - * Traffic control messages. - ****/ - -struct tcmsg -{ - unsigned char tcm_family; - unsigned char tcm__pad1; - unsigned short tcm__pad2; - int tcm_ifindex; - __u32 tcm_handle; - __u32 tcm_parent; - __u32 tcm_info; -}; - -enum -{ - TCA_UNSPEC, - TCA_KIND, - TCA_OPTIONS, - TCA_STATS, - TCA_XSTATS, - TCA_RATE, - TCA_FCNT, - TCA_STATS2, - __TCA_MAX -}; - -#define TCA_MAX (__TCA_MAX - 1) - -#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg)))) -#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg)) - -/* RTnetlink multicast groups - backwards compatibility for userspace */ -#define RTMGRP_LINK 1 -#define RTMGRP_NOTIFY 2 -#define RTMGRP_NEIGH 4 -#define RTMGRP_TC 8 - -#define RTMGRP_IPV4_IFADDR 0x10 -#define RTMGRP_IPV4_MROUTE 0x20 -#define RTMGRP_IPV4_ROUTE 0x40 - -#define RTMGRP_IPV6_IFADDR 0x100 -#define RTMGRP_IPV6_MROUTE 0x200 -#define RTMGRP_IPV6_ROUTE 0x400 -#define RTMGRP_IPV6_IFINFO 0x800 - -#define RTMGRP_DECnet_IFADDR 0x1000 -#define RTMGRP_DECnet_ROUTE 0x4000 - -#define RTMGRP_IPV6_PREFIX 0x20000 - -/* RTnetlink multicast groups */ -enum rtnetlink_groups { - RTNLGRP_NONE, -#define RTNLGRP_NONE RTNLGRP_NONE - RTNLGRP_LINK, -#define RTNLGRP_LINK RTNLGRP_LINK - RTNLGRP_NOTIFY, -#define RTNLGRP_NOTIFY RTNLGRP_NOTIFY - RTNLGRP_NEIGH, -#define RTNLGRP_NEIGH RTNLGRP_NEIGH - RTNLGRP_TC, -#define RTNLGRP_TC RTNLGRP_TC - RTNLGRP_IPV4_IFADDR, -#define RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_IFADDR - RTNLGRP_IPV4_MROUTE, -#define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE - RTNLGRP_IPV4_ROUTE, -#define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE - RTNLGRP_NOP1, - RTNLGRP_IPV6_IFADDR, -#define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR - RTNLGRP_IPV6_MROUTE, -#define RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_MROUTE - RTNLGRP_IPV6_ROUTE, -#define RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_ROUTE - RTNLGRP_IPV6_IFINFO, -#define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO - RTNLGRP_DECnet_IFADDR, -#define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR - RTNLGRP_NOP2, - RTNLGRP_DECnet_ROUTE, -#define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE - RTNLGRP_NOP3, - RTNLGRP_NOP4, - RTNLGRP_IPV6_PREFIX, -#define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX - __RTNLGRP_MAX -}; -#define RTNLGRP_MAX (__RTNLGRP_MAX - 1) - -/* TC action piece */ -struct tcamsg -{ - unsigned char tca_family; - unsigned char tca__pad1; - unsigned short tca__pad2; -}; -#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg)))) -#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg)) -#define TCA_ACT_TAB 1 /* attr type must be >=1 */ -#define TCAA_MAX 1 - -/* End of information exported to user level */ - - - -#endif /* __LINUX_RTNETLINK_H */ diff --git a/include/linux/socket.h b/include/linux/socket.h deleted file mode 100644 index dc979c0..0000000 --- a/include/linux/socket.h +++ /dev/null @@ -1 +0,0 @@ -#include <sys/socket.h> diff --git a/include/linux/tc_act/tc_defact.h b/include/linux/tc_act/tc_defact.h deleted file mode 100644 index 964f473..0000000 --- a/include/linux/tc_act/tc_defact.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __LINUX_TC_DEF_H -#define __LINUX_TC_DEF_H - -#include <linux/pkt_cls.h> - -struct tc_defact -{ - tc_gen; -}; - -enum -{ - TCA_DEF_UNSPEC, - TCA_DEF_TM, - TCA_DEF_PARMS, - TCA_DEF_DATA, - __TCA_DEF_MAX -}; -#define TCA_DEF_MAX (__TCA_DEF_MAX - 1) - -#endif diff --git a/include/linux/tc_act/tc_gact.h b/include/linux/tc_act/tc_gact.h deleted file mode 100644 index 23a03eb..0000000 --- a/include/linux/tc_act/tc_gact.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __LINUX_TC_GACT_H -#define __LINUX_TC_GACT_H - -#include <linux/pkt_cls.h> - -#define TCA_ACT_GACT 5 -struct tc_gact -{ - tc_gen; - -}; - -struct tc_gact_p -{ -#define PGACT_NONE 0 -#define PGACT_NETRAND 1 -#define PGACT_DETERM 2 -#define MAX_RAND (PGACT_DETERM + 1 ) - __u16 ptype; - __u16 pval; - int paction; -}; - -enum -{ - TCA_GACT_UNSPEC, - TCA_GACT_TM, - TCA_GACT_PARMS, - TCA_GACT_PROB, - __TCA_GACT_MAX -}; -#define TCA_GACT_MAX (__TCA_GACT_MAX - 1) - -#endif diff --git a/include/linux/tc_act/tc_ipt.h b/include/linux/tc_act/tc_ipt.h deleted file mode 100644 index 4b6f7b6..0000000 --- a/include/linux/tc_act/tc_ipt.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __LINUX_TC_IPT_H -#define __LINUX_TC_IPT_H - -#include <linux/pkt_cls.h> - -#define TCA_ACT_IPT 6 - -enum -{ - TCA_IPT_UNSPEC, - TCA_IPT_TABLE, - TCA_IPT_HOOK, - TCA_IPT_INDEX, - TCA_IPT_CNT, - TCA_IPT_TM, - TCA_IPT_TARG, - __TCA_IPT_MAX -}; -#define TCA_IPT_MAX (__TCA_IPT_MAX - 1) - -#endif diff --git a/include/linux/tc_act/tc_mirred.h b/include/linux/tc_act/tc_mirred.h deleted file mode 100644 index 71d6340..0000000 --- a/include/linux/tc_act/tc_mirred.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __LINUX_TC_MIR_H -#define __LINUX_TC_MIR_H - -#include <linux/pkt_cls.h> - -#define TCA_ACT_MIRRED 8 -#define TCA_EGRESS_REDIR 1 /* packet redirect to EGRESS*/ -#define TCA_EGRESS_MIRROR 2 /* mirror packet to EGRESS */ -#define TCA_INGRESS_REDIR 3 /* packet redirect to INGRESS*/ -#define TCA_INGRESS_MIRROR 4 /* mirror packet to INGRESS */ - -struct tc_mirred -{ - tc_gen; - int eaction; /* one of IN/EGRESS_MIRROR/REDIR */ - __u32 ifindex; /* ifindex of egress port */ -}; - -enum -{ - TCA_MIRRED_UNSPEC, - TCA_MIRRED_TM, - TCA_MIRRED_PARMS, - __TCA_MIRRED_MAX -}; -#define TCA_MIRRED_MAX (__TCA_MIRRED_MAX - 1) - -#endif diff --git a/include/linux/tc_act/tc_pedit.h b/include/linux/tc_act/tc_pedit.h deleted file mode 100644 index 83e56e3..0000000 --- a/include/linux/tc_act/tc_pedit.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __LINUX_TC_PED_H -#define __LINUX_TC_PED_H - -#include <linux/pkt_cls.h> - -#define TCA_ACT_PEDIT 7 - -enum -{ - TCA_PEDIT_UNSPEC, - TCA_PEDIT_TM, - TCA_PEDIT_PARMS, - __TCA_PEDIT_MAX -}; -#define TCA_PEDIT_MAX (__TCA_PEDIT_MAX - 1) - -struct tc_pedit_key -{ - __u32 mask; /* AND */ - __u32 val; /*XOR */ - __u32 off; /*offset */ - __u32 at; - __u32 offmask; - __u32 shift; -}; - -struct tc_pedit_sel -{ - tc_gen; - unsigned char nkeys; - unsigned char flags; - struct tc_pedit_key keys[0]; -}; -#define tc_pedit tc_pedit_sel - -#endif diff --git a/include/linux/tc_ematch/tc_em_cmp.h b/include/linux/tc_ematch/tc_em_cmp.h deleted file mode 100644 index c7f4d43..0000000 --- a/include/linux/tc_ematch/tc_em_cmp.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __LINUX_TC_EM_CMP_H -#define __LINUX_TC_EM_CMP_H - -#include <linux/pkt_cls.h> - -struct tcf_em_cmp -{ - __u32 val; - __u32 mask; - __u16 off; - __u8 align:4; - __u8 flags:4; - __u8 layer:4; - __u8 opnd:4; -}; - -enum -{ - TCF_EM_ALIGN_U8 = 1, - TCF_EM_ALIGN_U16 = 2, - TCF_EM_ALIGN_U32 = 4 -}; - -#define TCF_EM_CMP_TRANS 1 - -#endif diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h deleted file mode 100644 index e21937c..0000000 --- a/include/linux/tc_ematch/tc_em_meta.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef __LINUX_TC_EM_META_H -#define __LINUX_TC_EM_META_H - -#include <linux/pkt_cls.h> - -enum -{ - TCA_EM_META_UNSPEC, - TCA_EM_META_HDR, - TCA_EM_META_LVALUE, - TCA_EM_META_RVALUE, - __TCA_EM_META_MAX -}; -#define TCA_EM_META_MAX (__TCA_EM_META_MAX - 1) - -struct tcf_meta_val -{ - __u16 kind; - __u8 shift; - __u8 op; -}; - -#define TCF_META_TYPE_MASK (0xf << 12) -#define TCF_META_TYPE(kind) (((kind) & TCF_META_TYPE_MASK) >> 12) -#define TCF_META_ID_MASK 0x7ff -#define TCF_META_ID(kind) ((kind) & TCF_META_ID_MASK) - -enum -{ - TCF_META_TYPE_VAR, - TCF_META_TYPE_INT, - __TCF_META_TYPE_MAX -}; -#define TCF_META_TYPE_MAX (__TCF_META_TYPE_MAX - 1) - -enum -{ - TCF_META_ID_VALUE, - TCF_META_ID_RANDOM, - TCF_META_ID_LOADAVG_0, - TCF_META_ID_LOADAVG_1, - TCF_META_ID_LOADAVG_2, - TCF_META_ID_DEV, - TCF_META_ID_PRIORITY, - TCF_META_ID_PROTOCOL, - TCF_META_ID_PKTTYPE, - TCF_META_ID_PKTLEN, - TCF_META_ID_DATALEN, - TCF_META_ID_MACLEN, - TCF_META_ID_NFMARK, - TCF_META_ID_TCINDEX, - TCF_META_ID_RTCLASSID, - TCF_META_ID_RTIIF, - TCF_META_ID_SK_FAMILY, - TCF_META_ID_SK_STATE, - TCF_META_ID_SK_REUSE, - TCF_META_ID_SK_BOUND_IF, - TCF_META_ID_SK_REFCNT, - TCF_META_ID_SK_SHUTDOWN, - TCF_META_ID_SK_PROTO, - TCF_META_ID_SK_TYPE, - TCF_META_ID_SK_RCVBUF, - TCF_META_ID_SK_RMEM_ALLOC, - TCF_META_ID_SK_WMEM_ALLOC, - TCF_META_ID_SK_OMEM_ALLOC, - TCF_META_ID_SK_WMEM_QUEUED, - TCF_META_ID_SK_RCV_QLEN, - TCF_META_ID_SK_SND_QLEN, - TCF_META_ID_SK_ERR_QLEN, - TCF_META_ID_SK_FORWARD_ALLOCS, - TCF_META_ID_SK_SNDBUF, - TCF_META_ID_SK_ALLOCS, - TCF_META_ID_SK_ROUTE_CAPS, - TCF_META_ID_SK_HASH, - TCF_META_ID_SK_LINGERTIME, - TCF_META_ID_SK_ACK_BACKLOG, - TCF_META_ID_SK_MAX_ACK_BACKLOG, - TCF_META_ID_SK_PRIO, - TCF_META_ID_SK_RCVLOWAT, - TCF_META_ID_SK_RCVTIMEO, - TCF_META_ID_SK_SNDTIMEO, - TCF_META_ID_SK_SENDMSG_OFF, - TCF_META_ID_SK_WRITE_PENDING, - __TCF_META_ID_MAX -}; -#define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1) - -struct tcf_meta_hdr -{ - struct tcf_meta_val left; - struct tcf_meta_val right; -}; - -#endif diff --git a/include/linux/tc_ematch/tc_em_nbyte.h b/include/linux/tc_ematch/tc_em_nbyte.h deleted file mode 100644 index f19d1f5..0000000 --- a/include/linux/tc_ematch/tc_em_nbyte.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __LINUX_TC_EM_NBYTE_H -#define __LINUX_TC_EM_NBYTE_H - -#include <linux/pkt_cls.h> - -struct tcf_em_nbyte -{ - __u16 off; - __u16 len:12; - __u8 layer:4; -}; - -#endif diff --git a/include/linux/tcp.h b/include/linux/tcp.h deleted file mode 100644 index b4d74eb..0000000 --- a/include/linux/tcp.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Definitions for the TCP protocol. - * - * Version: @(#)tcp.h 1.0.2 04/28/93 - * - * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _LINUX_TCP_H -#define _LINUX_TCP_H - -#include <linux/types.h> -#include <asm/byteorder.h> - -struct tcphdr { - __u16 source; - __u16 dest; - __u32 seq; - __u32 ack_seq; -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u16 res1:4, - doff:4, - fin:1, - syn:1, - rst:1, - psh:1, - ack:1, - urg:1, - ece:1, - cwr:1; -#elif defined(__BIG_ENDIAN_BITFIELD) - __u16 doff:4, - res1:4, - cwr:1, - ece:1, - urg:1, - ack:1, - psh:1, - rst:1, - syn:1, - fin:1; -#else -#error "Adjust your <asm/byteorder.h> defines" -#endif - __u16 window; - __u16 check; - __u16 urg_ptr; -}; - -/* - * The union cast uses a gcc extension to avoid aliasing problems - * (union is compatible to any of its members) - * This means this part of the code is -fstrict-aliasing safe now. - */ -union tcp_word_hdr { - struct tcphdr hdr; - __u32 words[5]; -}; - -#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3]) - -enum { - TCP_FLAG_CWR = __constant_htonl(0x00800000), - TCP_FLAG_ECE = __constant_htonl(0x00400000), - TCP_FLAG_URG = __constant_htonl(0x00200000), - TCP_FLAG_ACK = __constant_htonl(0x00100000), - TCP_FLAG_PSH = __constant_htonl(0x00080000), - TCP_FLAG_RST = __constant_htonl(0x00040000), - TCP_FLAG_SYN = __constant_htonl(0x00020000), - TCP_FLAG_FIN = __constant_htonl(0x00010000), - TCP_RESERVED_BITS = __constant_htonl(0x0F000000), - TCP_DATA_OFFSET = __constant_htonl(0xF0000000) -}; - -/* TCP socket options */ -#define TCP_NODELAY 1 /* Turn off Nagle's algorithm. */ -#define TCP_MAXSEG 2 /* Limit MSS */ -#define TCP_CORK 3 /* Never send partially complete segments */ -#define TCP_KEEPIDLE 4 /* Start keeplives after this period */ -#define TCP_KEEPINTVL 5 /* Interval between keepalives */ -#define TCP_KEEPCNT 6 /* Number of keepalives before death */ -#define TCP_SYNCNT 7 /* Number of SYN retransmits */ -#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */ -#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */ -#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */ -#define TCP_INFO 11 /* Information about this connection. */ -#define TCP_QUICKACK 12 /* Block/reenable quick acks */ -#define TCP_CONGESTION 13 /* Congestion control algorithm */ - -#define TCPI_OPT_TIMESTAMPS 1 -#define TCPI_OPT_SACK 2 -#define TCPI_OPT_WSCALE 4 -#define TCPI_OPT_ECN 8 - -enum tcp_ca_state -{ - TCP_CA_Open = 0, -#define TCPF_CA_Open (1<<TCP_CA_Open) - TCP_CA_Disorder = 1, -#define TCPF_CA_Disorder (1<<TCP_CA_Disorder) - TCP_CA_CWR = 2, -#define TCPF_CA_CWR (1<<TCP_CA_CWR) - TCP_CA_Recovery = 3, -#define TCPF_CA_Recovery (1<<TCP_CA_Recovery) - TCP_CA_Loss = 4 -#define TCPF_CA_Loss (1<<TCP_CA_Loss) -}; - -struct tcp_info -{ - __u8 tcpi_state; - __u8 tcpi_ca_state; - __u8 tcpi_retransmits; - __u8 tcpi_probes; - __u8 tcpi_backoff; - __u8 tcpi_options; - __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; - - __u32 tcpi_rto; - __u32 tcpi_ato; - __u32 tcpi_snd_mss; - __u32 tcpi_rcv_mss; - - __u32 tcpi_unacked; - __u32 tcpi_sacked; - __u32 tcpi_lost; - __u32 tcpi_retrans; - __u32 tcpi_fackets; - - /* Times. */ - __u32 tcpi_last_data_sent; - __u32 tcpi_last_ack_sent; /* Not remembered, sorry. */ - __u32 tcpi_last_data_recv; - __u32 tcpi_last_ack_recv; - - /* Metrics. */ - __u32 tcpi_pmtu; - __u32 tcpi_rcv_ssthresh; - __u32 tcpi_rtt; - __u32 tcpi_rttvar; - __u32 tcpi_snd_ssthresh; - __u32 tcpi_snd_cwnd; - __u32 tcpi_advmss; - __u32 tcpi_reordering; - - __u32 tcpi_rcv_rtt; - __u32 tcpi_rcv_space; - - __u32 tcpi_total_retrans; -}; - - -#endif /* _LINUX_TCP_H */ diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h deleted file mode 100644 index f2bbf4b..0000000 --- a/include/linux/xfrm.h +++ /dev/null @@ -1,311 +0,0 @@ -#ifndef _LINUX_XFRM_H -#define _LINUX_XFRM_H - -#include <linux/types.h> - -/* All of the structures in this file may not change size as they are - * passed into the kernel from userspace via netlink sockets. - */ - -/* Structure to encapsulate addresses. I do not want to use - * "standard" structure. My apologies. - */ -typedef union -{ - __u32 a4; - __u32 a6[4]; -} xfrm_address_t; - -/* Ident of a specific xfrm_state. It is used on input to lookup - * the state by (spi,daddr,ah/esp) or to store information about - * spi, protocol and tunnel address on output. - */ -struct xfrm_id -{ - xfrm_address_t daddr; - __u32 spi; - __u8 proto; -}; - -struct xfrm_sec_ctx { - __u8 ctx_doi; - __u8 ctx_alg; - __u16 ctx_len; - __u32 ctx_sid; - char ctx_str[0]; -}; - -/* Security Context Domains of Interpretation */ -#define XFRM_SC_DOI_RESERVED 0 -#define XFRM_SC_DOI_LSM 1 - -/* Security Context Algorithms */ -#define XFRM_SC_ALG_RESERVED 0 -#define XFRM_SC_ALG_SELINUX 1 - -/* Selector, used as selector both on policy rules (SPD) and SAs. */ - -struct xfrm_selector -{ - xfrm_address_t daddr; - xfrm_address_t saddr; - __u16 dport; - __u16 dport_mask; - __u16 sport; - __u16 sport_mask; - __u16 family; - __u8 prefixlen_d; - __u8 prefixlen_s; - __u8 proto; - int ifindex; - uid_t user; -}; - -#define XFRM_INF (~(__u64)0) - -struct xfrm_lifetime_cfg -{ - __u64 soft_byte_limit; - __u64 hard_byte_limit; - __u64 soft_packet_limit; - __u64 hard_packet_limit; - __u64 soft_add_expires_seconds; - __u64 hard_add_expires_seconds; - __u64 soft_use_expires_seconds; - __u64 hard_use_expires_seconds; -}; - -struct xfrm_lifetime_cur -{ - __u64 bytes; - __u64 packets; - __u64 add_time; - __u64 use_time; -}; - -struct xfrm_replay_state -{ - __u32 oseq; - __u32 seq; - __u32 bitmap; -}; - -struct xfrm_algo { - char alg_name[64]; - int alg_key_len; /* in bits */ - char alg_key[0]; -}; - -struct xfrm_stats { - __u32 replay_window; - __u32 replay; - __u32 integrity_failed; -}; - -enum -{ - XFRM_POLICY_IN = 0, - XFRM_POLICY_OUT = 1, - XFRM_POLICY_FWD = 2, - XFRM_POLICY_MAX = 3 -}; - -enum -{ - XFRM_SHARE_ANY, /* No limitations */ - XFRM_SHARE_SESSION, /* For this session only */ - XFRM_SHARE_USER, /* For this user only */ - XFRM_SHARE_UNIQUE /* Use once */ -}; - -/* Netlink configuration messages. */ -enum { - XFRM_MSG_BASE = 0x10, - - XFRM_MSG_NEWSA = 0x10, -#define XFRM_MSG_NEWSA XFRM_MSG_NEWSA - XFRM_MSG_DELSA, -#define XFRM_MSG_DELSA XFRM_MSG_DELSA - XFRM_MSG_GETSA, -#define XFRM_MSG_GETSA XFRM_MSG_GETSA - - XFRM_MSG_NEWPOLICY, -#define XFRM_MSG_NEWPOLICY XFRM_MSG_NEWPOLICY - XFRM_MSG_DELPOLICY, -#define XFRM_MSG_DELPOLICY XFRM_MSG_DELPOLICY - XFRM_MSG_GETPOLICY, -#define XFRM_MSG_GETPOLICY XFRM_MSG_GETPOLICY - - XFRM_MSG_ALLOCSPI, -#define XFRM_MSG_ALLOCSPI XFRM_MSG_ALLOCSPI - XFRM_MSG_ACQUIRE, -#define XFRM_MSG_ACQUIRE XFRM_MSG_ACQUIRE - XFRM_MSG_EXPIRE, -#define XFRM_MSG_EXPIRE XFRM_MSG_EXPIRE - - XFRM_MSG_UPDPOLICY, -#define XFRM_MSG_UPDPOLICY XFRM_MSG_UPDPOLICY - XFRM_MSG_UPDSA, -#define XFRM_MSG_UPDSA XFRM_MSG_UPDSA - - XFRM_MSG_POLEXPIRE, -#define XFRM_MSG_POLEXPIRE XFRM_MSG_POLEXPIRE - - XFRM_MSG_FLUSHSA, -#define XFRM_MSG_FLUSHSA XFRM_MSG_FLUSHSA - XFRM_MSG_FLUSHPOLICY, -#define XFRM_MSG_FLUSHPOLICY XFRM_MSG_FLUSHPOLICY - - __XFRM_MSG_MAX -}; -#define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) - -#define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE) - -/* - * Generic LSM security context for comunicating to user space - * NOTE: Same format as sadb_x_sec_ctx - */ -struct xfrm_user_sec_ctx { - __u16 len; - __u16 exttype; - __u8 ctx_alg; /* LSMs: e.g., selinux == 1 */ - __u8 ctx_doi; - __u16 ctx_len; -}; - -struct xfrm_user_tmpl { - struct xfrm_id id; - __u16 family; - xfrm_address_t saddr; - __u32 reqid; - __u8 mode; - __u8 share; - __u8 optional; - __u32 aalgos; - __u32 ealgos; - __u32 calgos; -}; - -struct xfrm_encap_tmpl { - __u16 encap_type; - __u16 encap_sport; - __u16 encap_dport; - xfrm_address_t encap_oa; -}; - -/* Netlink message attributes. */ -enum xfrm_attr_type_t { - XFRMA_UNSPEC, - XFRMA_ALG_AUTH, /* struct xfrm_algo */ - XFRMA_ALG_CRYPT, /* struct xfrm_algo */ - XFRMA_ALG_COMP, /* struct xfrm_algo */ - XFRMA_ENCAP, /* struct xfrm_algo + struct xfrm_encap_tmpl */ - XFRMA_TMPL, /* 1 or more struct xfrm_user_tmpl */ - XFRMA_SA, - XFRMA_POLICY, - XFRMA_SEC_CTX, /* struct xfrm_sec_ctx */ - __XFRMA_MAX - -#define XFRMA_MAX (__XFRMA_MAX - 1) -}; - -struct xfrm_usersa_info { - struct xfrm_selector sel; - struct xfrm_id id; - xfrm_address_t saddr; - struct xfrm_lifetime_cfg lft; - struct xfrm_lifetime_cur curlft; - struct xfrm_stats stats; - __u32 seq; - __u32 reqid; - __u16 family; - __u8 mode; /* 0=transport,1=tunnel */ - __u8 replay_window; - __u8 flags; -#define XFRM_STATE_NOECN 1 -#define XFRM_STATE_DECAP_DSCP 2 -#define XFRM_STATE_NOPMTUDISC 4 -}; - -struct xfrm_usersa_id { - xfrm_address_t daddr; - __u32 spi; - __u16 family; - __u8 proto; -}; - -struct xfrm_userspi_info { - struct xfrm_usersa_info info; - __u32 min; - __u32 max; -}; - -struct xfrm_userpolicy_info { - struct xfrm_selector sel; - struct xfrm_lifetime_cfg lft; - struct xfrm_lifetime_cur curlft; - __u32 priority; - __u32 index; - __u8 dir; - __u8 action; -#define XFRM_POLICY_ALLOW 0 -#define XFRM_POLICY_BLOCK 1 - __u8 flags; -#define XFRM_POLICY_LOCALOK 1 /* Allow user to override global policy */ - __u8 share; -}; - -struct xfrm_userpolicy_id { - struct xfrm_selector sel; - __u32 index; - __u8 dir; -}; - -struct xfrm_user_acquire { - struct xfrm_id id; - xfrm_address_t saddr; - struct xfrm_selector sel; - struct xfrm_userpolicy_info policy; - __u32 aalgos; - __u32 ealgos; - __u32 calgos; - __u32 seq; -}; - -struct xfrm_user_expire { - struct xfrm_usersa_info state; - __u8 hard; -}; - -struct xfrm_user_polexpire { - struct xfrm_userpolicy_info pol; - __u8 hard; -}; - -struct xfrm_usersa_flush { - __u8 proto; -}; - -/* backwards compatibility for userspace */ -#define XFRMGRP_ACQUIRE 1 -#define XFRMGRP_EXPIRE 2 -#define XFRMGRP_SA 4 -#define XFRMGRP_POLICY 8 - -enum xfrm_nlgroups { - XFRMNLGRP_NONE, -#define XFRMNLGRP_NONE XFRMNLGRP_NONE - XFRMNLGRP_ACQUIRE, -#define XFRMNLGRP_ACQUIRE XFRMNLGRP_ACQUIRE - XFRMNLGRP_EXPIRE, -#define XFRMNLGRP_EXPIRE XFRMNLGRP_EXPIRE - XFRMNLGRP_SA, -#define XFRMNLGRP_SA XFRMNLGRP_SA - XFRMNLGRP_POLICY, -#define XFRMNLGRP_POLICY XFRMNLGRP_POLICY - __XFRMNLGRP_MAX -}; -#define XFRMNLGRP_MAX (__XFRMNLGRP_MAX - 1) - -#endif /* _LINUX_XFRM_H */ diff --git a/include/ll_map.h b/include/ll_map.h deleted file mode 100644 index d085813..0000000 --- a/include/ll_map.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __LL_MAP_H__ -#define __LL_MAP_H__ 1 - -extern int ll_remember_index(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg); -extern int ll_init_map(struct rtnl_handle *rth); -extern unsigned ll_name_to_index(const char *name); -extern const char *ll_index_to_name(unsigned idx); -extern const char *ll_idx_n2a(unsigned idx, char *buf); -extern int ll_index_to_type(unsigned idx); -extern unsigned ll_index_to_flags(unsigned idx); - -#endif /* __LL_MAP_H__ */ diff --git a/include/net/tcp_states.h b/include/net/tcp_states.h deleted file mode 100644 index b0b6459..0000000 --- a/include/net/tcp_states.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Definitions for the TCP protocol sk_state field. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _LINUX_TCP_STATES_H -#define _LINUX_TCP_STATES_H - -enum { - TCP_ESTABLISHED = 1, - TCP_SYN_SENT, - TCP_SYN_RECV, - TCP_FIN_WAIT1, - TCP_FIN_WAIT2, - TCP_TIME_WAIT, - TCP_CLOSE, - TCP_CLOSE_WAIT, - TCP_LAST_ACK, - TCP_LISTEN, - TCP_CLOSING, /* Now a valid state */ - - TCP_MAX_STATES /* Leave at the end! */ -}; - -#define TCP_STATE_MASK 0xF - -#define TCP_ACTION_FIN (1 << 7) - -enum { - TCPF_ESTABLISHED = (1 << 1), - TCPF_SYN_SENT = (1 << 2), - TCPF_SYN_RECV = (1 << 3), - TCPF_FIN_WAIT1 = (1 << 4), - TCPF_FIN_WAIT2 = (1 << 5), - TCPF_TIME_WAIT = (1 << 6), - TCPF_CLOSE = (1 << 7), - TCPF_CLOSE_WAIT = (1 << 8), - TCPF_LAST_ACK = (1 << 9), - TCPF_LISTEN = (1 << 10), - TCPF_CLOSING = (1 << 11) -}; - -#endif /* _LINUX_TCP_STATES_H */ diff --git a/include/rt_names.h b/include/rt_names.h deleted file mode 100644 index 2d9ef10..0000000 --- a/include/rt_names.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef RT_NAMES_H_ -#define RT_NAMES_H_ 1 - -#include <asm/types.h> - -char* rtnl_rtprot_n2a(int id, char *buf, int len); -char* rtnl_rtscope_n2a(int id, char *buf, int len); -char* rtnl_rttable_n2a(int id, char *buf, int len); -char* rtnl_rtrealm_n2a(int id, char *buf, int len); -char* rtnl_dsfield_n2a(int id, char *buf, int len); -int rtnl_rtprot_a2n(__u32 *id, char *arg); -int rtnl_rtscope_a2n(__u32 *id, char *arg); -int rtnl_rttable_a2n(__u32 *id, char *arg); -int rtnl_rtrealm_a2n(__u32 *id, char *arg); -int rtnl_dsfield_a2n(__u32 *id, char *arg); - -const char *inet_proto_n2a(int proto, char *buf, int len); -int inet_proto_a2n(char *buf); - - -const char * ll_type_n2a(int type, char *buf, int len); - -const char *ll_addr_n2a(unsigned char *addr, int alen, int type, char *buf, int blen); -int ll_addr_a2n(char *lladdr, int len, char *arg); - -const char * ll_proto_n2a(unsigned short id, char *buf, int len); -int ll_proto_a2n(unsigned short *id, char *buf); - - -#endif diff --git a/include/rtm_map.h b/include/rtm_map.h deleted file mode 100644 index 70bda7d..0000000 --- a/include/rtm_map.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __RTM_MAP_H__ -#define __RTM_MAP_H__ 1 - -char *rtnl_rtntype_n2a(int id, char *buf, int len); -int rtnl_rtntype_a2n(int *id, char *arg); - -int get_rt_realms(__u32 *realms, char *arg); - - -#endif /* __RTM_MAP_H__ */ diff --git a/include/utils.h b/include/utils.h deleted file mode 100644 index 0f1d1f6..0000000 --- a/include/utils.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef __UTILS_H__ -#define __UTILS_H__ 1 - -#include <asm/types.h> -#include <resolv.h> - -#include "libnetlink.h" -#include "ll_map.h" -#include "rtm_map.h" - -extern int preferred_family; -extern int show_stats; -extern int show_details; -extern int show_raw; -extern int resolve_hosts; -extern int oneline; -extern int timestamp; -extern char * _SL_; - -#ifndef IPPROTO_ESP -#define IPPROTO_ESP 50 -#endif -#ifndef IPPROTO_AH -#define IPPROTO_AH 51 -#endif -#ifndef IPPROTO_COMP -#define IPPROTO_COMP 108 -#endif -#ifndef IPSEC_PROTO_ANY -#define IPSEC_PROTO_ANY 255 -#endif - -#define SPRINT_BSIZE 64 -#define SPRINT_BUF(x) char x[SPRINT_BSIZE] - -extern void incomplete_command(void) __attribute__((noreturn)); - -#define NEXT_ARG() do { argv++; if (--argc <= 0) incomplete_command(); } while(0) -#define NEXT_ARG_OK() (argc - 1 > 0) -#define PREV_ARG() do { argv--; argc++; } while(0) - -typedef struct -{ - __u8 family; - __u8 bytelen; - __s16 bitlen; - __u32 flags; - __u32 data[4]; -} inet_prefix; - -#define PREFIXLEN_SPECIFIED 1 - -#define DN_MAXADDL 20 -#ifndef AF_DECnet -#define AF_DECnet 12 -#endif - -struct dn_naddr -{ - unsigned short a_len; - unsigned char a_addr[DN_MAXADDL]; -}; - -#define IPX_NODE_LEN 6 - -struct ipx_addr { - u_int32_t ipx_net; - u_int8_t ipx_node[IPX_NODE_LEN]; -}; - -extern __u32 get_addr32(const char *name); -extern int get_addr_1(inet_prefix *dst, const char *arg, int family); -extern int get_prefix_1(inet_prefix *dst, char *arg, int family); -extern int get_addr(inet_prefix *dst, const char *arg, int family); -extern int get_prefix(inet_prefix *dst, char *arg, int family); - -extern int get_integer(int *val, const char *arg, int base); -extern int get_unsigned(unsigned *val, const char *arg, int base); -#define get_byte get_u8 -#define get_ushort get_u16 -#define get_short get_s16 -extern int get_u64(__u64 *val, const char *arg, int base); -extern int get_u32(__u32 *val, const char *arg, int base); -extern int get_u16(__u16 *val, const char *arg, int base); -extern int get_s16(__s16 *val, const char *arg, int base); -extern int get_u8(__u8 *val, const char *arg, int base); -extern int get_s8(__s8 *val, const char *arg, int base); - -extern char* hexstring_n2a(const __u8 *str, int len, char *buf, int blen); -extern __u8* hexstring_a2n(const char *str, __u8 *buf, int blen); - -extern const char *format_host(int af, int len, const void *addr, - char *buf, int buflen); -extern const char *rt_addr_n2a(int af, int len, const void *addr, - char *buf, int buflen); - -void missarg(const char *) __attribute__((noreturn)); -void invarg(const char *, const char *) __attribute__((noreturn)); -void duparg(const char *, const char *) __attribute__((noreturn)); -void duparg2(const char *, const char *) __attribute__((noreturn)); -int matches(const char *arg, const char *pattern); -extern int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits); - -const char *dnet_ntop(int af, const void *addr, char *str, size_t len); -int dnet_pton(int af, const char *src, void *addr); - -const char *ipx_ntop(int af, const void *addr, char *str, size_t len); -int ipx_pton(int af, const char *src, void *addr); - -extern int __iproute2_hz_internal; -extern int __get_hz(void); - -static __inline__ int get_hz(void) -{ - if (__iproute2_hz_internal == 0) - __iproute2_hz_internal = __get_hz(); - return __iproute2_hz_internal; -} - -extern int __iproute2_user_hz_internal; -extern int __get_user_hz(void); - -static __inline__ int get_user_hz(void) -{ - if (__iproute2_user_hz_internal == 0) - __iproute2_user_hz_internal = __get_user_hz(); - return __iproute2_user_hz_internal; -} - -int print_timestamp(FILE *fp); - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -extern int cmdlineno; -extern size_t getcmdline(char **line, size_t *len, FILE *in); -extern int makeargs(char *line, char *argv[], int maxargs); - -#endif /* __UTILS_H__ */ diff --git a/ip.8 b/ip.8 deleted file mode 100644 index 50e4419..0000000 --- a/ip.8 +++ /dev/null @@ -1,1809 +0,0 @@ -.TH IP 8 "17 January 2002" "iproute2" "Linux" -.SH NAME -ip \- show / manipulate routing, devices, policy routing and tunnels -.SH SYNOPSIS - -.ad l -.in +8 -.ti -8 -.B ip -.RI "[ " OPTIONS " ] " OBJECT " { " COMMAND " | " -.BR help " }" -.sp - -.ti -8 -.IR OBJECT " := { " -.BR link " | " addr " | " route " | " rule " | " neigh " | " tunnel " | "\ -maddr " | " mroute " | " monitor " }" -.sp - -.ti -8 -.IR OPTIONS " := { " -\fB\-V\fR[\fIersion\fR] | -\fB\-s\fR[\fItatistics\fR] | -\fB\-r\fR[\fIesolve\fR] | -\fB\-f\fR[\fIamily\fR] { -.BR inet " | " inet6 " | " ipx " | " dnet " | " link " } | " -\fB\-o\fR[\fIneline\fR] } - -.ti -8 -.BI "ip link set " DEVICE -.RB "{ " up " | " down " | " arp " { " on " | " off " } |" -.br -.BR promisc " { " on " | " off " } |" -.br -.BR allmulti " { " on " | " off " } |" -.br -.BR dynamic " { " on " | " off " } |" -.br -.BR multicast " { " on " | " off " } |" -.br -.B txqueuelen -.IR PACKETS " |" -.br -.B name -.IR NEWNAME " |" -.br -.B address -.IR LLADDR " |" -.B broadcast -.IR LLADDR " |" -.br -.B mtu -.IR MTU " }" - -.ti -8 -.B ip link show -.RI "[ " DEVICE " ]" - -.ti -8 -.BR "ip addr" " { " add " | " del " } " -.IB IFADDR " dev " STRING - -.ti -8 -.BR "ip addr" " { " show " | " flush " } [ " dev -.IR STRING " ] [ " -.B scope -.IR SCOPE-ID " ] [ " -.B to -.IR PREFIX " ] [ " FLAG-LIST " ] [ " -.B label -.IR PATTERN " ]" - -.ti -8 -.IR IFADDR " := " PREFIX " | " ADDR -.B peer -.IR PREFIX " [ " -.B broadcast -.IR ADDR " ] [ " -.B anycast -.IR ADDR " ] [ " -.B label -.IR STRING " ] [ " -.B scope -.IR SCOPE-ID " ]" - -.ti -8 -.IR SCOPE-ID " := " -.RB "[ " host " | " link " | " global " | " -.IR NUMBER " ]" - -.ti -8 -.IR FLAG-LIST " := [ " FLAG-LIST " ] " FLAG - -.ti -8 -.IR FLAG " := " -.RB "[ " permanent " | " dynamic " | " secondary " | " primary " | "\ -tentative " | " deprecated " ]" - -.ti -8 -.BR "ip route" " { " -.BR list " | " flush " } " -.I SELECTOR - -.ti -8 -.B ip route get -.IR ADDRESS " [ " -.BI from " ADDRESS " iif " STRING" -.RB " ] [ " oif -.IR STRING " ] [ " -.B tos -.IR TOS " ]" - -.ti -8 -.BR "ip route" " { " add " | " del " | " change " | " append " | "\ -replace " | " monitor " } " -.I ROUTE - -.ti -8 -.IR SELECTOR " := " -.RB "[ " root -.IR PREFIX " ] [ " -.B match -.IR PREFIX " ] [ " -.B exact -.IR PREFIX " ] [ " -.B table -.IR TABLE_ID " ] [ " -.B proto -.IR RTPROTO " ] [ " -.B type -.IR TYPE " ] [ " -.B scope -.IR SCOPE " ]" - -.ti -8 -.IR ROUTE " := " NODE_SPEC " [ " INFO_SPEC " ]" - -.ti -8 -.IR NODE_SPEC " := [ " TYPE " ] " PREFIX " [" -.B tos -.IR TOS " ] [ " -.B table -.IR TABLE_ID " ] [ " -.B proto -.IR RTPROTO " ] [ " -.B scope -.IR SCOPE " ] [ " -.B metric -.IR METRIC " ]" - -.ti -8 -.IR INFO_SPEC " := " "NH OPTIONS FLAGS" " [" -.B nexthop -.IR NH " ] ..." - -.ti -8 -.IR NH " := [ " -.B via -.IR ADDRESS " ] [ " -.B dev -.IR STRING " ] [ " -.B weight -.IR NUMBER " ] " NHFLAGS - -.ti -8 -.IR OPTIONS " := " FLAGS " [ " -.B mtu -.IR NUMBER " ] [ " -.B advmss -.IR NUMBER " ] [ " -.B rtt -.IR NUMBER " ] [ " -.B rttvar -.IR NUMBER " ] [ " -.B window -.IR NUMBER " ] [ " -.B cwnd -.IR NUMBER " ] [ " -.B ssthresh -.IR REALM " ] [ " -.B realms -.IR REALM " ]" - -.ti -8 -.IR TYPE " := [ " -.BR unicast " | " local " | " broadcast " | " multicast " | "\ -throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]" - -.ti -8 -.IR TABLE_ID " := [ " -.BR local "| " main " | " default " | " all " |" -.IR NUMBER " ]" - -.ti -8 -.IR SCOPE " := [ " -.BR host " | " link " | " global " |" -.IR NUMBER " ]" - -.ti -8 -.IR FLAGS " := [ " -.BR equalize " ]" - -.ti -8 -.IR NHFLAGS " := [ " -.BR onlink " | " pervasive " ]" - -.ti -8 -.IR RTPROTO " := [ " -.BR kernel " | " boot " | " static " |" -.IR NUMBER " ]" - -.ti -8 -.B ip rule -.RB " [ " list " | " add " | " del " ]" -.I SELECTOR ACTION - -.ti -8 -.IR SELECTOR " := [ " -.B from -.IR PREFIX " ] [ " -.B to -.IR PREFIX " ] [ " -.B tos -.IR TOS " ] [ " -.B fwmark -.IR FWMARK " ] [ " -.B dev -.IR STRING " ] [ " -.B pref -.IR NUMBER " ]" - -.ti -8 -.IR ACTION " := [ " -.B table -.IR TABLE_ID " ] [ " -.B nat -.IR ADDRESS " ] [ " -.BR prohibit " | " reject " | " unreachable " ] [ " realms -.RI "[" SRCREALM "/]" DSTREALM " ]" - -.ti -8 -.IR TABLE_ID " := [ " -.BR local " | " main " | " default " |" -.IR NUMBER " ]" - -.ti -8 -.BR "ip neigh" " { " add " | " del " | " change " | " replace " } { " -.IR ADDR " [ " -.B lladdr -.IR LLADDR " ] [ " -.BR nud " { " permanent " | " noarp " | " stale " | " reachable " } ] | " proxy -.IR ADDR " } [ " -.B dev -.IR DEV " ]" - -.ti -8 -.BR "ip neigh" " { " show " | " flush " } [ " to -.IR PREFIX " ] [ " -.B dev -.IR DEV " ] [ " -.B nud -.IR STATE " ]" - -.ti -8 -.BR "ip tunnel" " { " add " | " change " | " del " | " show " }" -.RI "[ " NAME " ]" -.br -.RB "[ " mode " { " ipip " | " gre " | " sit " } ]" -.br -.RB "[ " remote -.IR ADDR " ] [ " -.B local -.IR ADDR " ]" -.br -.RB "[ [" i "|" o "]" seq " ] [ [" i "|" o "]" key -.IR KEY " ] [ " -.RB "[" i "|" o "]" csum " ] ]" -.br -.RB "[ " ttl -.IR TTL " ] [ " -.B tos -.IR TOS " ] [ " -.RB "[" no "]" pmtudisc " ]" -.br -.RB "[ " dev -.IR PHYS_DEV " ]" - -.ti -8 -.IR ADDR " := { " IP_ADDRESS " |" -.BR any " }" - -.ti -8 -.IR TOS " := { " NUMBER " |" -.BR inherit " }" - -.ti -8 -.IR TTL " := { " 1 ".." 255 " | " -.BR inherit " }" - -.ti -8 -.IR KEY " := { " DOTTED_QUAD " | " NUMBER " }" - -.ti -8 -.BR "ip maddr" " [ " add " | " del " ]" -.IB MULTIADDR " dev " STRING - -.ti -8 -.BR "ip maddr show" " [ " dev -.IR STRING " ]" - -.ti -8 -.BR "ip mroute show" " [" -.IR PREFIX " ] [ " -.B from -.IR PREFIX " ] [ " -.B iif -.IR DEVICE " ]" - -.ti -8 -.BR "ip monitor" " [ " all " |" -.IR LISTofOBJECTS " ]" -.in -8 -.ad b - -.SH OPTIONS - -.TP -.BR "\-V" , " -Version" -print the version of the -.B ip -utility and exit. - -.TP -.BR "\-s" , " \-stats", " \-statistics" -output more information. If the option -appears twice or more, the amount of information increases. -As a rule, the information is statistics or some time values. - -.TP -.BR "\-f" , " \-family" -followed by protocol family identifier: -.BR "inet" , " inet6" -or -.B link -,enforce the protocol family to use. If the option is not present, -the protocol family is guessed from other arguments. If the rest -of the command line does not give enough information to guess the -family, -.B ip -falls back to the default one, usually -.B inet -or -.BR "any" . -.B link -is a special family identifier meaning that no networking protocol -is involved. - -.TP -.B \-4 -shortcut for -.BR "-family inet" . - -.TP -.B \-6 -shortcut for -.BR "\-family inet6" . - -.TP -.B \-0 -shortcut for -.BR "\-family link" . - -.TP -.BR "\-o" , " \-oneline" -output each record on a single line, replacing line feeds -with the -.B '\' -character. This is convenient when you want to count records -with -.BR wc (1) - or to -.BR grep (1) -the output. - -.TP -.BR "\-r" , " \-resolve" -use the system's name resolver to print DNS names instead of -host addresses. - -.SH IP - COMMAND SYNTAX - -.SS -.I OBJECT - -.TP -.B link -- network device. - -.TP -.B address -- protocol (IP or IPv6) address on a device. -.TP -.B neighbour -- ARP or NDISC cache entry. - -.TP -.B route -- routing table entry. - -.TP -.B rule -- rule in routing policy database. - -.TP -.B maddress -- multicast address. - -.TP -.B mroute -- multicast routing cache entry. - -.TP -.B tunnel -- tunnel over IP. - -.PP -The names of all objects may be written in full or -abbreviated form, f.e. -.B address -is abbreviated as -.B addr -or just -.B a. - -.SS -.I COMMAND - -Specifies the action to perform on the object. -The set of possible actions depends on the object type. -As a rule, it is possible to -.BR "add" , " delete" -and -.B show -(or -.B list -) objects, but some objects do not allow all of these operations -or have some additional commands. The -.B help -command is available for all objects. It prints -out a list of available commands and argument syntax conventions. -.sp -If no command is given, some default command is assumed. -Usually it is -.B list -or, if the objects of this class cannot be listed, -.BR "help" . - -.SH ip link - network device configuration - -.B link -is a network device and the corresponding commands -display and change the state of devices. - -.SS ip link set - change device attributes - -.TP -.BI dev " NAME " (default) -.I NAME -specifies network device to operate on. - -.TP -.BR up " and " down -change the state of the device to -.B UP -or -.BR "DOWN" . - -.TP -.BR "arp on " or " arp off" -change the -.B NOARP -flag on the device. - -.TP -.BR "multicast on " or " multicast off" -change the -.B MULTICAST -flag on the device. - -.TP -.BR "dynamic on " or " dynamic off" -change the -.B DYNAMIC -flag on the device. - -.TP -.BI name " NAME" -change the name of the device. This operation is not -recommended if the device is running or has some addresses -already configured. - -.TP -.BI txqueuelen " NUMBER" -.TP -.BI txqlen " NUMBER" -change the transmit queue length of the device. - -.TP -.BI mtu " NUMBER" -change the -.I MTU -of the device. - -.TP -.BI address " LLADDRESS" -change the station address of the interface. - -.TP -.BI broadcast " LLADDRESS" -.TP -.BI brd " LLADDRESS" -.TP -.BI peer " LLADDRESS" -change the link layer broadcast address or the peer address when -the interface is -.IR "POINTOPOINT" . - -.PP -.B Warning: -If multiple parameter changes are requested, -.B ip -aborts immediately after any of the changes have failed. -This is the only case when -.B ip -can move the system to an unpredictable state. The solution -is to avoid changing several parameters with one -.B ip link set -call. - -.SS ip link show - display device attributes - -.TP -.BI dev " NAME " (default) -.I NAME -specifies the network device to show. -If this argument is omitted all devices are listed. - -.TP -.B up -only display running interfaces. - -.SH ip address - protocol address management. - -The -.B address -is a protocol (IP or IPv6) address attached -to a network device. Each device must have at least one address -to use the corresponding protocol. It is possible to have several -different addresses attached to one device. These addresses are not -discriminated, so that the term -.B alias -is not quite appropriate for them and we do not use it in this document. -.sp -The -.B ip addr -command displays addresses and their properties, adds new addresses -and deletes old ones. - -.SS ip address add - add new protocol address. - -.TP -.BI dev " NAME" -the name of the device to add the address to. - -.TP -.BI local " ADDRESS " (default) -the address of the interface. The format of the address depends -on the protocol. It is a dotted quad for IP and a sequence of -hexadecimal halfwords separated by colons for IPv6. The -.I ADDRESS -may be followed by a slash and a decimal number which encodes -the network prefix length. - -.TP -.BI peer " ADDRESS" -the address of the remote endpoint for pointopoint interfaces. -Again, the -.I ADDRESS -may be followed by a slash and a decimal number, encoding the network -prefix length. If a peer address is specified, the local address -cannot have a prefix length. The network prefix is associated -with the peer rather than with the local address. - -.TP -.BI broadcast " ADDRESS" -the broadcast address on the interface. -.sp -It is possible to use the special symbols -.B '+' -and -.B '-' -instead of the broadcast address. In this case, the broadcast address -is derived by setting/resetting the host bits of the interface prefix. - -.TP -.BI label " NAME" -Each address may be tagged with a label string. -In order to preserve compatibility with Linux-2.0 net aliases, -this string must coincide with the name of the device or must be prefixed -with the device name followed by colon. - -.TP -.BI scope " SCOPE_VALUE" -the scope of the area where this address is valid. -The available scopes are listed in file -.BR "/etc/iproute2/rt_scopes" . -Predefined scope values are: - -.in +8 -.B global -- the address is globally valid. -.sp -.B site -- (IPv6 only) the address is site local, i.e. it is -valid inside this site. -.sp -.B link -- the address is link local, i.e. it is valid only on this device. -.sp -.B host -- the address is valid only inside this host. -.in -8 - -.SS ip address delete - delete protocol address -.B Arguments: -coincide with the arguments of -.B ip addr add. -The device name is a required argument. The rest are optional. -If no arguments are given, the first address is deleted. - -.SS ip address show - look at protocol addresses - -.TP -.BI dev " NAME " (default) -name of device. - -.TP -.BI scope " SCOPE_VAL" -only list addresses with this scope. - -.TP -.BI to " PREFIX" -only list addresses matching this prefix. - -.TP -.BI label " PATTERN" -only list addresses with labels matching the -.IR "PATTERN" . -.I PATTERN -is a usual shell style pattern. - -.TP -.BR dynamic " and " permanent -(IPv6 only) only list addresses installed due to stateless -address configuration or only list permanent (not dynamic) -addresses. - -.TP -.B tentative -(IPv6 only) only list addresses which did not pass duplicate -address detection. - -.TP -.B deprecated -(IPv6 only) only list deprecated addresses. - -.TP -.BR primary " and " secondary -only list primary (or secondary) addresses. - -.SS ip address flush - flush protocol addresses -This command flushes the protocol addresses selected by some criteria. - -.PP -This command has the same arguments as -.B show. -The difference is that it does not run when no arguments are given. - -.PP -.B Warning: -This command (and other -.B flush -commands described below) is pretty dangerous. If you make a mistake, -it will not forgive it, but will cruelly purge all the addresses. - -.PP -With the -.B -statistics -option, the command becomes verbose. It prints out the number of deleted -addresses and the number of rounds made to flush the address list. If -this option is given twice, -.B ip addr flush -also dumps all the deleted addresses in the format described in the -previous subsection. - -.SH ip neighbour - neighbour/arp tables management. - -.B neighbour -objects establish bindings between protocol addresses and -link layer addresses for hosts sharing the same link. -Neighbour entries are organized into tables. The IPv4 neighbour table -is known by another name - the ARP table. - -.P -The corresponding commands display neighbour bindings -and their properties, add new neighbour entries and delete old ones. - -.SS ip neighbour add - add a new neighbour entry -.SS ip neighbour change - change an existing entry -.SS ip neighbour replace - add a new entry or change an existing one - -These commands create new neighbour records or update existing ones. - -.TP -.BI to " ADDRESS " (default) -the protocol address of the neighbour. It is either an IPv4 or IPv6 address. - -.TP -.BI dev " NAME" -the interface to which this neighbour is attached. - -.TP -.BI lladdr " LLADDRESS" -the link layer address of the neighbour. -.I LLADDRESS -can also be -.BR "null" . - -.TP -.BI nud " NUD_STATE" -the state of the neighbour entry. -.B nud -is an abbreviation for 'Neigh bour Unreachability Detection'. -The state can take one of the following values: - -.in +8 -.B permanent -- the neighbour entry is valid forever and can be only -be removed administratively. -.sp - -.B noarp -- the neighbour entry is valid. No attempts to validate -this entry will be made but it can be removed when its lifetime expires. -.sp - -.B reachable -- the neighbour entry is valid until the reachability -timeout expires. -.sp - -.B stale -- the neighbour entry is valid but suspicious. -This option to -.B ip neigh -does not change the neighbour state if it was valid and the address -is not changed by this command. -.in -8 - -.SS ip neighbour delete - delete a neighbour entry -This command invalidates a neighbour entry. - -.PP -The arguments are the same as with -.BR "ip neigh add" , -except that -.B lladdr -and -.B nud -are ignored. - -.PP -.B Warning: -Attempts to delete or manually change a -.B noarp -entry created by the kernel may result in unpredictable behaviour. -Particularly, the kernel may try to resolve this address even -on a -.B NOARP -interface or if the address is multicast or broadcast. - -.SS ip neighbour show - list neighbour entries - -This commands displays neighbour tables. - -.TP -.BI to " ADDRESS " (default) -the prefix selecting the neighbours to list. - -.TP -.BI dev " NAME" -only list the neighbours attached to this device. - -.TP -.B unused -only list neighbours which are not currently in use. - -.TP -.BI nud " NUD_STATE" -only list neighbour entries in this state. -.I NUD_STATE -takes values listed below or the special value -.B all -which means all states. This option may occur more than once. -If this option is absent, -.B ip -lists all entries except for -.B none -and -.BR "noarp" . - -.SS ip neighbour flush - flush neighbour entries -This command flushes neighbour tables, selecting -entries to flush by some criteria. - -.PP -This command has the same arguments as -.B show. -The differences are that it does not run when no arguments are given, -and that the default neighbour states to be flushed do not include -.B permanent -and -.BR "noarp" . - -.PP -With the -.B -statistics -option, the command becomes verbose. It prints out the number of -deleted neighbours and the number of rounds made to flush the -neighbour table. If the option is given -twice, -.B ip neigh flush -also dumps all the deleted neighbours. - -.SH ip route - routing table management -Manipulate route entries in the kernel routing tables keep -information about paths to other networked nodes. -.sp -.B Route types: - -.in +8 -.B unicast -- the route entry describes real paths to the destinations covered -by the route prefix. - -.sp -.B unreachable -- these destinations are unreachable. Packets are discarded and the -ICMP message -.I host unreachable -is generated. -The local senders get an -.I EHOSTUNREACH -error. - -.sp -.B blackhole -- these destinations are unreachable. Packets are discarded silently. -The local senders get an -.I EINVAL -error. - -.sp -.B prohibit -- these destinations are unreachable. Packets are discarded and the -ICMP message -.I communication administratively prohibited -is generated. The local senders get an -.I EACCES -error. - -.sp -.B local -- the destinations are assigned to this host. The packets are looped -back and delivered locally. - -.sp -.B broadcast -- the destinations are broadcast addresses. The packets are sent as -link broadcasts. - -.sp -.B throw -- a special control route used together with policy rules. If such a -route is selected, lookup in this table is terminated pretending that -no route was found. Without policy routing it is equivalent to the -absence of the route in the routing table. The packets are dropped -and the ICMP message -.I net unreachable -is generated. The local senders get an -.I ENETUNREACH -error. - -.sp -.B nat -- a special NAT route. Destinations covered by the prefix -are considered to be dummy (or external) addresses which require translation -to real (or internal) ones before forwarding. The addresses to translate to -are selected with the attribute -.BR "via" . - -.sp -.B anycast -.RI "- " "not implemented" -the destinations are -.I anycast -addresses assigned to this host. They are mainly equivalent -to -.B local -with one difference: such addresses are invalid when used -as the source address of any packet. - -.sp -.B multicast -- a special type used for multicast routing. It is not present in -normal routing tables. -.in -8 - -.P -.B Route tables: -Linux-2.x can pack routes into several routing -tables identified by a number in the range from 1 to 255 or by -name from the file -.B /etc/iproute2/rt_tables -. By default all normal routes are inserted into the -.B main -table (ID 254) and the kernel only uses this table when calculating routes. - -.sp -Actually, one other table always exists, which is invisible but -even more important. It is the -.B local -table (ID 255). This table -consists of routes for local and broadcast addresses. The kernel maintains -this table automatically and the administrator usually need not modify it -or even look at it. - -The multiple routing tables enter the game when -.I policy routing -is used. - -.SS ip route add - add new route -.SS ip route change - change route -.SS ip route replace - change or add new one - -.TP -.BI to " TYPE PREFIX " (default) -the destination prefix of the route. If -.I TYPE -is omitted, -.B ip -assumes type -.BR "unicast" . -Other values of -.I TYPE -are listed above. -.I PREFIX -is an IP or IPv6 address optionally followed by a slash and the -prefix length. If the length of the prefix is missing, -.B ip -assumes a full-length host route. There is also a special -.I PREFIX -.B default -- which is equivalent to IP -.B 0/0 -or to IPv6 -.BR "::/0" . - -.TP -.BI tos " TOS" -.TP -.BI dsfield " TOS" -the Type Of Service (TOS) key. This key has no associated mask and -the longest match is understood as: First, compare the TOS -of the route and of the packet. If they are not equal, then the packet -may still match a route with a zero TOS. -.I TOS -is either an 8 bit hexadecimal number or an identifier -from -.BR "/etc/iproute2/rt_dsfield" . - -.TP -.BI metric " NUMBER" -.TP -.BI preference " NUMBER" -the preference value of the route. -.I NUMBER -is an arbitrary 32bit number. - -.TP -.BI table " TABLEID" -the table to add this route to. -.I TABLEID -may be a number or a string from the file -.BR "/etc/iproute2/rt_tables" . -If this parameter is omitted, -.B ip -assumes the -.B main -table, with the exception of -.BR local " , " broadcast " and " nat -routes, which are put into the -.B local -table by default. - -.TP -.BI dev " NAME" -the output device name. - -.TP -.BI via " ADDRESS" -the address of the nexthop router. Actually, the sense of this field -depends on the route type. For normal -.B unicast -routes it is either the true next hop router or, if it is a direct -route installed in BSD compatibility mode, it can be a local address -of the interface. For NAT routes it is the first address of the block -of translated IP destinations. - -.TP -.BI src " ADDRESS" -the source address to prefer when sending to the destinations -covered by the route prefix. - -.TP -.BI realm " REALMID" -the realm to which this route is assigned. -.I REALMID -may be a number or a string from the file -.BR "/etc/iproute2/rt_realms" . - -.TP -.BI mtu " MTU" -.TP -.BI "mtu lock" " MTU" -the MTU along the path to the destination. If the modifier -.B lock -is not used, the MTU may be updated by the kernel due to -Path MTU Discovery. If the modifier -.B lock -is used, no path MTU discovery will be tried, all packets -will be sent without the DF bit in IPv4 case or fragmented -to MTU for IPv6. - -.TP -.BI window " NUMBER" -the maximal window for TCP to advertise to these destinations, -measured in bytes. It limits maximal data bursts that our TCP -peers are allowed to send to us. - -.TP -.BI rtt " NUMBER" -the initial RTT ('Round Trip Time') estimate. - -.TP -.BI rttvar " NUMBER " "(2.3.15+ only)" -the initial RTT variance estimate. - -.TP -.BI ssthresh " NUMBER " "(2.3.15+ only)" -an estimate for the initial slow start threshold. - -.TP -.BI cwnd " NUMBER " "(2.3.15+ only)" -the clamp for congestion window. It is ignored if the -.B lock -flag is not used. - -.TP -.BI advmss " NUMBER " "(2.3.15+ only)" -the MSS ('Maximal Segment Size') to advertise to these -destinations when establishing TCP connections. If it is not given, -Linux uses a default value calculated from the first hop device MTU. -(If the path to these destination is asymmetric, this guess may be wrong.) - -.TP -.BI reordering " NUMBER " "(2.3.15+ only)" -Maximal reordering on the path to this destination. -If it is not given, Linux uses the value selected with -.B sysctl -variable -.BR "net/ipv4/tcp_reordering" . - -.TP -.BI nexthop " NEXTHOP" -the nexthop of a multipath route. -.I NEXTHOP -is a complex value with its own syntax similar to the top level -argument lists: - -.in +8 -.BI via " ADDRESS" -- is the nexthop router. -.sp - -.BI dev " NAME" -- is the output device. -.sp - -.BI weight " NUMBER" -- is a weight for this element of a multipath -route reflecting its relative bandwidth or quality. -.in -8 - -.TP -.BI scope " SCOPE_VAL" -the scope of the destinations covered by the route prefix. -.I SCOPE_VAL -may be a number or a string from the file -.BR "/etc/iproute2/rt_scopes" . -If this parameter is omitted, -.B ip -assumes scope -.B global -for all gatewayed -.B unicast -routes, scope -.B link -for direct -.BR unicast " and " broadcast -routes and scope -.BR host " for " local -routes. - -.TP -.BI protocol " RTPROTO" -the routing protocol identifier of this route. -.I RTPROTO -may be a number or a string from the file -.BR "/etc/iproute2/rt_protos" . -If the routing protocol ID is not given, -.B ip assumes protocol -.B boot -(i.e. it assumes the route was added by someone who doesn't -understand what they are doing). Several protocol values have -a fixed interpretation. -Namely: - -.in +8 -.B redirect -- the route was installed due to an ICMP redirect. -.sp - -.B kernel -- the route was installed by the kernel during autoconfiguration. -.sp - -.B boot -- the route was installed during the bootup sequence. -If a routing daemon starts, it will purge all of them. -.sp - -.B static -- the route was installed by the administrator -to override dynamic routing. Routing daemon will respect them -and, probably, even advertise them to its peers. -.sp - -.B ra -- the route was installed by Router Discovery protocol. -.in -8 - -.sp -The rest of the values are not reserved and the administrator is free -to assign (or not to assign) protocol tags. - -.TP -.B onlink -pretend that the nexthop is directly attached to this link, -even if it does not match any interface prefix. - -.TP -.B equalize -allow packet by packet randomization on multipath routes. -Without this modifier, the route will be frozen to one selected -nexthop, so that load splitting will only occur on per-flow base. -.B equalize -only works if the kernel is patched. - -.SS ip route delete - delete route - -.B ip route del -has the same arguments as -.BR "ip route add" , -but their semantics are a bit different. - -Key values -.RB "(" to ", " tos ", " preference " and " table ")" -select the route to delete. If optional attributes are present, -.B ip -verifies that they coincide with the attributes of the route to delete. -If no route with the given key and attributes was found, -.B ip route del -fails. - -.SS ip route show - list routes -the command displays the contents of the routing tables or the route(s) -selected by some criteria. - -.TP -.BI to " SELECTOR " (default) -only select routes from the given range of destinations. -.I SELECTOR -consists of an optional modifier -.RB "(" root ", " match " or " exact ")" -and a prefix. -.BI root " PREFIX" -selects routes with prefixes not shorter than -.IR PREFIX "." -F.e. -.BI root " 0/0" -selects the entire routing table. -.BI match " PREFIX" -selects routes with prefixes not longer than -.IR PREFIX "." -F.e. -.BI match " 10.0/16" -selects -.IR 10.0/16 "," -.IR 10/8 " and " 0/0 , -but it does not select -.IR 10.1/16 " and " 10.0.0/24 . -And -.BI exact " PREFIX" -(or just -.IR PREFIX ")" -selects routes with this exact prefix. If neither of these options -are present, -.B ip -assumes -.BI root " 0/0" -i.e. it lists the entire table. - -.TP -.BI tos " TOS" -.BI dsfield " TOS" -only select routes with the given TOS. - -.TP -.BI table " TABLEID" -show the routes from this table(s). The default setting is to show -.BR table main "." -.I TABLEID -may either be the ID of a real table or one of the special values: -.sp -.in +8 -.B all -- list all of the tables. -.sp -.B cache -- dump the routing cache. -.in -8 - -.TP -.B cloned -.TP -.B cached -list cloned routes i.e. routes which were dynamically forked from -other routes because some route attribute (f.e. MTU) was updated. -Actually, it is equivalent to -.BR "table cache" "." - -.TP -.BI from " SELECTOR" -the same syntax as for -.BR to "," -but it binds the source address range rather than destinations. -Note that the -.B from -option only works with cloned routes. - -.TP -.BI protocol " RTPROTO" -only list routes of this protocol. - -.TP -.BI scope " SCOPE_VAL" -only list routes with this scope. - -.TP -.BI type " TYPE" -only list routes of this type. - -.TP -.BI dev " NAME" -only list routes going via this device. - -.TP -.BI via " PREFIX" -only list routes going via the nexthop routers selected by -.IR PREFIX "." - -.TP -.BI src " PREFIX" -only list routes with preferred source addresses selected -by -.IR PREFIX "." - -.TP -.BI realm " REALMID" -.TP -.BI realms " FROMREALM/TOREALM" -only list routes with these realms. - -.SS ip route flush - flush routing tables -this command flushes routes selected by some criteria. - -.sp -The arguments have the same syntax and semantics as the arguments of -.BR "ip route show" , -but routing tables are not listed but purged. The only difference is -the default action: -.B show -dumps all the IP main routing table but -.B flush -prints the helper page. - -.sp -With the -.B -statistics -option, the command becomes verbose. It prints out the number of -deleted routes and the number of rounds made to flush the routing -table. If the option is given -twice, -.B ip route flush -also dumps all the deleted routes in the format described in the -previous subsection. - -.SS ip route get - get a single route -this command gets a single route to a destination and prints its -contents exactly as the kernel sees it. - -.TP -.BI to " ADDRESS " (default) -the destination address. - -.TP -.BI from " ADDRESS" -the source address. - -.TP -.BI tos " TOS" -.TP -.BI dsfield " TOS" -the Type Of Service. - -.TP -.BI iif " NAME" -the device from which this packet is expected to arrive. - -.TP -.BI oif " NAME" -force the output device on which this packet will be routed. - -.TP -.B connected -if no source address -.RB "(option " from ")" -was given, relookup the route with the source set to the preferred -address received from the first lookup. -If policy routing is used, it may be a different route. - -.P -Note that this operation is not equivalent to -.BR "ip route show" . -.B show -shows existing routes. -.B get -resolves them and creates new clones if necessary. Essentially, -.B get -is equivalent to sending a packet along this path. -If the -.B iif -argument is not given, the kernel creates a route -to output packets towards the requested destination. -This is equivalent to pinging the destination -with a subsequent -.BR "ip route ls cache" , -however, no packets are actually sent. With the -.B iif -argument, the kernel pretends that a packet arrived from this interface -and searches for a path to forward the packet. - -.SH ip rule - routing policy database management - -.BR "Rule" s -in the routing policy database control the route selection algorithm. - -.P -Classic routing algorithms used in the Internet make routing decisions -based only on the destination address of packets (and in theory, -but not in practice, on the TOS field). - -.P -In some circumstances we want to route packets differently depending not only -on destination addresses, but also on other packet fields: source address, -IP protocol, transport protocol ports or even packet payload. -This task is called 'policy routing'. - -.P -To solve this task, the conventional destination based routing table, ordered -according to the longest match rule, is replaced with a 'routing policy -database' (or RPDB), which selects routes by executing some set of rules. - -.P -Each policy routing rule consists of a -.B selector -and an -.B action predicate. -The RPDB is scanned in the order of increasing priority. The selector -of each rule is applied to {source address, destination address, incoming -interface, tos, fwmark} and, if the selector matches the packet, -the action is performed. The action predicate may return with success. -In this case, it will either give a route or failure indication -and the RPDB lookup is terminated. Otherwise, the RPDB program -continues on the next rule. - -.P -Semantically, natural action is to select the nexthop and the output device. - -.P -At startup time the kernel configures the default RPDB consisting of three -rules: - -.TP -1. -Priority: 0, Selector: match anything, Action: lookup routing -table -.B local -(ID 255). -The -.B local -table is a special routing table containing -high priority control routes for local and broadcast addresses. -.sp -Rule 0 is special. It cannot be deleted or overridden. - -.TP -2. -Priority: 32766, Selector: match anything, Action: lookup routing -table -.B main -(ID 254). -The -.B main -table is the normal routing table containing all non-policy -routes. This rule may be deleted and/or overridden with other -ones by the administrator. - -.TP -3. -Priority: 32767, Selector: match anything, Action: lookup routing -table -.B default -(ID 253). -The -.B default -table is empty. It is reserved for some post-processing if no previous -default rules selected the packet. -This rule may also be deleted. - -.P -Each RPDB entry has additional -attributes. F.e. each rule has a pointer to some routing -table. NAT and masquerading rules have an attribute to select new IP -address to translate/masquerade. Besides that, rules have some -optional attributes, which routes have, namely -.BR "realms" . -These values do not override those contained in the routing tables. They -are only used if the route did not select any attributes. - -.sp -The RPDB may contain rules of the following types: - -.in +8 -.B unicast -- the rule prescribes to return the route found -in the routing table referenced by the rule. - -.B blackhole -- the rule prescribes to silently drop the packet. - -.B unreachable -- the rule prescribes to generate a 'Network is unreachable' error. - -.B prohibit -- the rule prescribes to generate 'Communication is administratively -prohibited' error. - -.B nat -- the rule prescribes to translate the source address -of the IP packet into some other value. -.in -8 - -.SS ip rule add - insert a new rule -.SS ip rule delete - delete a rule - -.TP -.BI type " TYPE " (default) -the type of this rule. The list of valid types was given in the previous -subsection. - -.TP -.BI from " PREFIX" -select the source prefix to match. - -.TP -.BI to " PREFIX" -select the destination prefix to match. - -.TP -.BI iif " NAME" -select the incoming device to match. If the interface is loopback, -the rule only matches packets originating from this host. This means -that you may create separate routing tables for forwarded and local -packets and, hence, completely segregate them. - -.TP -.BI tos " TOS" -.TP -.BI dsfield " TOS" -select the TOS value to match. - -.TP -.BI fwmark " MARK" -select the -.B fwmark -value to match. - -.TP -.BI priority " PREFERENCE" -the priority of this rule. Each rule should have an explicitly -set -.I unique -priority value. - -.TP -.BI table " TABLEID" -the routing table identifier to lookup if the rule selector matches. - -.TP -.BI realms " FROM/TO" -Realms to select if the rule matched and the routing table lookup -succeeded. Realm -.I TO -is only used if the route did not select any realm. - -.TP -.BI nat " ADDRESS" -The base of the IP address block to translate (for source addresses). -The -.I ADDRESS -may be either the start of the block of NAT addresses (selected by NAT -routes) or a local host address (or even zero). -In the last case the router does not translate the packets, but -masquerades them to this address. - -.B Warning: -Changes to the RPDB made with these commands do not become active -immediately. It is assumed that after a script finishes a batch of -updates, it flushes the routing cache with -.BR "ip route flush cache" . - -.SS ip rule show - list rules -This command has no arguments. - -.SH ip maddress - multicast addresses management - -.B maddress -objects are multicast addresses. - -.SS ip maddress show - list multicast addresses - -.TP -.BI dev " NAME " (default) -the device name. - -.SS ip maddress add - add a multicast address -.SS ip maddress delete - delete a multicast address -these commands attach/detach a static link layer multicast address -to listen on the interface. -Note that it is impossible to join protocol multicast groups -statically. This command only manages link layer addresses. - -.TP -.BI address " LLADDRESS " (default) -the link layer multicast address. - -.TP -.BI dev " NAME" -the device to join/leave this multicast address. - -.SH ip mroute - multicast routing cache management -.B mroute -objects are multicast routing cache entries created by a user level -mrouting daemon (f.e. -.B pimd -or -.B mrouted -). - -Due to the limitations of the current interface to the multicast routing -engine, it is impossible to change -.B mroute -objects administratively, so we may only display them. This limitation -will be removed in the future. - -.SS ip mroute show - list mroute cache entries - -.TP -.BI to " PREFIX " (default) -the prefix selecting the destination multicast addresses to list. - -.TP -.BI iif " NAME" -the interface on which multicast packets are received. - -.TP -.BI from " PREFIX" -the prefix selecting the IP source addresses of the multicast route. - -.SH ip tunnel - tunnel configuration -.B tunnel -objects are tunnels, encapsulating packets in IPv4 packets and then -sending them over the IP infrastructure. - -.SS ip tunnel add - add a new tunnel -.SS ip tunnel change - change an existing tunnel -.SS ip tunnel delete - destroy a tunnel - -.TP -.BI name " NAME " (default) -select the tunnel device name. - -.TP -.BI mode " MODE" -set the tunnel mode. Three modes are currently available: -.BR ipip ", " sit " and " gre "." - -.TP -.BI remote " ADDRESS" -set the remote endpoint of the tunnel. - -.TP -.BI local " ADDRESS" -set the fixed local address for tunneled packets. -It must be an address on another interface of this host. - -.TP -.BI ttl " N" -set a fixed TTL -.I N -on tunneled packets. -.I N -is a number in the range 1--255. 0 is a special value -meaning that packets inherit the TTL value. -The default value is: -.BR "inherit" . - -.TP -.BI tos " T" -.TP -.BI dsfield " T" -set a fixed TOS -.I T -on tunneled packets. -The default value is: -.BR "inherit" . - -.TP -.BI dev " NAME" -bind the tunnel to the device -.I NAME -so that tunneled packets will only be routed via this device and will -not be able to escape to another device when the route to endpoint -changes. - -.TP -.B nopmtudisc -disable Path MTU Discovery on this tunnel. -It is enabled by default. Note that a fixed ttl is incompatible -with this option: tunnelling with a fixed ttl always makes pmtu -discovery. - -.TP -.BI key " K" -.TP -.BI ikey " K" -.TP -.BI okey " K" -.RB ( " only GRE tunnels " ) -use keyed GRE with key -.IR K ". " K -is either a number or an IP address-like dotted quad. -The -.B key -parameter sets the key to use in both directions. -The -.BR ikey " and " okey -parameters set different keys for input and output. - -.TP -.BR csum ", " icsum ", " ocsum -.RB ( " only GRE tunnels " ) -generate/require checksums for tunneled packets. -The -.B ocsum -flag calculates checksums for outgoing packets. -The -.B icsum -flag requires that all input packets have the correct -checksum. The -.B csum -flag is equivalent to the combination -.BR "icsum ocsum" . - -.TP -.BR seq ", " iseq ", " oseq -.RB ( " only GRE tunnels " ) -serialize packets. -The -.B oseq -flag enables sequencing of outgoing packets. -The -.B iseq -flag requires that all input packets are serialized. -The -.B seq -flag is equivalent to the combination -.BR "iseq oseq" . -.B It isn't work. Don't use it. - -.SS ip tunnel show - list tunnels -This command has no arguments. - -.SH ip monitor and rtmon - state monitoring - -The -.B ip -utility can monitor the state of devices, addresses -and routes continuously. This option has a slightly different format. -Namely, the -.B monitor -command is the first in the command line and then the object list follows: - -.BR "ip monitor" " [ " all " |" -.IR LISTofOBJECTS " ]" - -.I OBJECT-LIST -is the list of object types that we want to monitor. -It may contain -.BR link ", " address " and " route "." -If no -.B file -argument is given, -.B ip -opens RTNETLINK, listens on it and dumps state changes in the format -described in previous sections. - -.P -If a file name is given, it does not listen on RTNETLINK, -but opens the file containing RTNETLINK messages saved in binary format -and dumps them. Such a history file can be generated with the -.B rtmon -utility. This utility has a command line syntax similar to -.BR "ip monitor" . -Ideally, -.B rtmon -should be started before the first network configuration command -is issued. F.e. if you insert: -.sp -.in +8 -rtmon file /var/log/rtmon.log -.in -8 -.sp -in a startup script, you will be able to view the full history -later. - -.P -Certainly, it is possible to start -.B rtmon -at any time. -It prepends the history with the state snapshot dumped at the moment -of starting. - -.SH HISTORY - -.B ip -was written by Alexey N. Kuznetsov and added in Linux 2.2. -.SH SEE ALSO -.BR tc (8) -.br -.RB "IP Command reference " ip-cref.ps -.br -.RB "IP tunnels " ip-cref.ps - -.SH AUTHOR - -Manpage maintained by Michail Litvak <mci@owl.openwall.com> diff --git a/ip/Makefile b/ip/Makefile deleted file mode 100644 index 3383c72..0000000 --- a/ip/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -IPOBJ=ip.o ipaddress.o iproute.o iprule.o \ - rtm_map.o iptunnel.o ipneigh.o ipntable.o iplink.o \ - ipmaddr.o ipmonitor.o ipmroute.o ipprefix.o \ - ipxfrm.o xfrm_state.o xfrm_policy.o xfrm_monitor.o - -RTMONOBJ=rtmon.o - -ALLOBJ=$(IPOBJ) $(RTMONOBJ) -SCRIPTS=ifcfg rtpr routel routef -TARGETS=ip rtmon - -all: $(TARGETS) $(SCRIPTS) - -ip: $(IPOBJ) $(LIBNETLINK) $(LIBUTIL) - -rtmon: $(RTMONOBJ) $(LIBNETLINK) - -install: all - install -m 0755 -s $(TARGETS) $(DESTDIR)$(SBINDIR) - install -m 0755 $(SCRIPTS) $(DESTDIR)$(SBINDIR) - -clean: - rm -f $(ALLOBJ) $(TARGETS) - diff --git a/ip/ifcfg b/ip/ifcfg deleted file mode 100755 index ed6960f..0000000 --- a/ip/ifcfg +++ /dev/null @@ -1,145 +0,0 @@ -#! /bin/bash - -CheckForwarding () { - local sbase fwd - sbase=/proc/sys/net/ipv4/conf - fwd=0 - if [ -d $sbase ]; then - for dir in $sbase/*/forwarding; do - fwd=$[$fwd + `cat $dir`] - done - else - fwd=2 - fi - return $fwd -} - -RestartRDISC () { - killall -HUP rdisc || rdisc -fs -} - -ABCMaskLen () { - local class; - - class=${1%%.*} - if [ "$1" = "" -o $class -eq 0 -o $class -ge 224 ]; then return 0 - elif [ $class -ge 224 ]; then return 0 - elif [ $class -ge 192 ]; then return 24 - elif [ $class -ge 128 ]; then return 16 - else return 8; fi -} - -label="label $1" -ldev="$1" -dev=${1%:*} -if [ "$dev" = "" -o "$1" = "help" ]; then - echo "Usage: ifcfg DEV [[add|del [ADDR[/LEN]] [PEER] | stop]" 1>&2 - echo " add - add new address" 1>&2 - echo " del - delete address" 1>&2 - echo " stop - completely disable IP" 1>&2 - exit 1 -fi -shift - -CheckForwarding -fwd=$? -if [ $fwd -ne 0 ]; then - echo "Forwarding is ON or its state is unknown ($fwd). OK, No RDISC." 1>&2 -fi - - -deleting=0 -case "$1" in -add) shift ;; -stop) - if [ "$ldev" != "$dev" ]; then - echo "Cannot stop alias $ldev" 1>&2 - exit 1; - fi - ip -4 addr flush dev $dev $label || exit 1 - if [ $fwd -eq 0 ]; then RestartRDISC; fi - exit 0 ;; -del*) - deleting=1; shift ;; -*) -esac - -ipaddr= -pfxlen= -if [ "$1" != "" ]; then - ipaddr=${1%/*} - if [ "$1" != "$ipaddr" ]; then - pfxlen=${1#*/} - fi - if [ "$ipaddr" = "" ]; then - echo "$1 is bad IP address." 1>&2 - exit 1 - fi -fi -shift - -peer=$1 -if [ "$peer" != "" ]; then - if [ "$pfxlen" != "" -a "$pfxlen" != "32" ]; then - echo "Peer address with non-trivial netmask." 1>&2 - exit 1 - fi - pfx="$ipaddr peer $peer" -else - if [ "$pfxlen" = "" ]; then - ABCMaskLen $ipaddr - pfxlen=$? - fi - pfx="$ipaddr/$pfxlen" -fi - -if [ "$ldev" = "$dev" -a "$ipaddr" != "" ]; then - label= -fi - -if [ $deleting -ne 0 ]; then - ip addr del $pfx dev $dev $label || exit 1 - if [ $fwd -eq 0 ]; then RestartRDISC; fi - exit 0 -fi - - -if ! ip link set up dev $dev ; then - echo "Error: cannot enable interface $dev." 1>&2 - exit 1 -fi -if [ "$ipaddr" = "" ]; then exit 0; fi - -if ! arping -q -c 2 -w 3 -D -I $dev $ipaddr ; then - echo "Error: some host already uses address $ipaddr on $dev." 1>&2 - exit 1 -fi - -if ! ip address add $pfx brd + dev $dev $label; then - echo "Error: failed to add $pfx on $dev." 1>&2 - exit 1 -fi - -arping -q -A -c 1 -I $dev $ipaddr -noarp=$? -( sleep 2 ; - arping -q -U -c 1 -I $dev $ipaddr ) >& /dev/null </dev/null & - -ip route add unreachable 224.0.0.0/24 >& /dev/null -ip route add unreachable 255.255.255.255 >& /dev/null -if [ `ip link ls $dev | grep -c MULTICAST` -ge 1 ]; then - ip route add 224.0.0.0/4 dev $dev scope global >& /dev/null -fi - -if [ $fwd -eq 0 ]; then - if [ $noarp -eq 0 ]; then - ip ro append default dev $dev metric 30000 scope global - elif [ "$peer" != "" ]; then - if ping -q -c 2 -w 4 $peer ; then - ip ro append default via $peer dev $dev metric 30001 - fi - fi - RestartRDISC -fi - -exit 0 diff --git a/ip/ip.c b/ip/ip.c deleted file mode 100644 index c29d2f3..0000000 --- a/ip/ip.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * ip.c "ip" utility frontend. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - * - * Changes: - * - * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <string.h> -#include <errno.h> - -#include "SNAPSHOT.h" -#include "utils.h" -#include "ip_common.h" - -int preferred_family = AF_UNSPEC; -int show_stats = 0; -int resolve_hosts = 0; -int oneline = 0; -int timestamp = 0; -char * _SL_ = NULL; -char *batch_file = NULL; -int force = 0; -struct rtnl_handle rth; - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, -"Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n" -" ip [ -force ] [-batch filename\n" -"where OBJECT := { link | addr | route | rule | neigh | ntable | tunnel |\n" -" maddr | mroute | monitor | xfrm }\n" -" OPTIONS := { -V[ersion] | -s[tatistics] | -r[esolve] |\n" -" -f[amily] { inet | inet6 | ipx | dnet | link } |\n" -" -o[neline] | -t[imestamp] }\n"); - exit(-1); -} - -static int do_help(int argc, char **argv) -{ - usage(); -} - -static const struct cmd { - const char *cmd; - int (*func)(int argc, char **argv); -} cmds[] = { - { "address", do_ipaddr }, - { "maddress", do_multiaddr }, - { "route", do_iproute }, - { "rule", do_iprule }, - { "neighbor", do_ipneigh }, - { "neighbour", do_ipneigh }, - { "ntable", do_ipntable }, - { "ntbl", do_ipntable }, - { "link", do_iplink }, - { "tunnel", do_iptunnel }, - { "tunl", do_iptunnel }, - { "monitor", do_ipmonitor }, - { "xfrm", do_xfrm }, - { "mroute", do_multiroute }, - { "help", do_help }, - { 0 } -}; - -static int do_cmd(const char *argv0, int argc, char **argv) -{ - const struct cmd *c; - - for (c = cmds; c->cmd; ++c) { - if (matches(argv0, c->cmd) == 0) - return c->func(argc-1, argv+1); - } - - fprintf(stderr, "Object \"%s\" is unknown, try \"ip help\".\n", argv0); - return -1; -} - -static int batch(const char *name) -{ - char *line = NULL; - size_t len = 0; - int ret = 0; - int lineno = 0; - - if (name && strcmp(name, "-") != 0) { - if (freopen(name, "r", stdin) == NULL) { - fprintf(stderr, "Cannot open file \"%s\" for reading: %s=n", - name, strerror(errno)); - return -1; - } - } - - if (rtnl_open(&rth, 0) < 0) { - fprintf(stderr, "Cannot open rtnetlink\n"); - return -1; - } - - while (getcmdline(&line, &len, stdin) != -1) { - char *largv[100]; - int largc; - - largc = makeargs(line, largv, 100); - if (largc == 0) - continue; /* blank line */ - - if (do_cmd(largv[0], largc, largv)) { - fprintf(stderr, "Command failed %s:%d\n", name, lineno); - ret = 1; - if (!force) - break; - } - } - if (line) - free(line); - - rtnl_close(&rth); - return ret; -} - - -int main(int argc, char **argv) -{ - char *basename; - - basename = strrchr(argv[0], '/'); - if (basename == NULL) - basename = argv[0]; - else - basename++; - - while (argc > 1) { - char *opt = argv[1]; - if (strcmp(opt,"--") == 0) { - argc--; argv++; - break; - } - if (opt[0] != '-') - break; - if (opt[1] == '-') - opt++; - if (matches(opt, "-family") == 0) { - argc--; - argv++; - if (argc <= 1) - usage(); - if (strcmp(argv[1], "inet") == 0) - preferred_family = AF_INET; - else if (strcmp(argv[1], "inet6") == 0) - preferred_family = AF_INET6; - else if (strcmp(argv[1], "dnet") == 0) - preferred_family = AF_DECnet; - else if (strcmp(argv[1], "link") == 0) - preferred_family = AF_PACKET; - else if (strcmp(argv[1], "ipx") == 0) - preferred_family = AF_IPX; - else if (strcmp(argv[1], "help") == 0) - usage(); - else - invarg(argv[1], "invalid protocol family"); - } else if (strcmp(opt, "-4") == 0) { - preferred_family = AF_INET; - } else if (strcmp(opt, "-6") == 0) { - preferred_family = AF_INET6; - } else if (strcmp(opt, "-0") == 0) { - preferred_family = AF_PACKET; - } else if (strcmp(opt, "-I") == 0) { - preferred_family = AF_IPX; - } else if (strcmp(opt, "-D") == 0) { - preferred_family = AF_DECnet; - } else if (matches(opt, "-stats") == 0 || - matches(opt, "-statistics") == 0) { - ++show_stats; - } else if (matches(opt, "-resolve") == 0) { - ++resolve_hosts; - } else if (matches(opt, "-oneline") == 0) { - ++oneline; - } else if (matches(opt, "-timestamp") == 0) { - ++timestamp; -#if 0 - } else if (matches(opt, "-numeric") == 0) { - rtnl_names_numeric++; -#endif - } else if (matches(opt, "-Version") == 0) { - printf("ip utility, iproute2-ss%s\n", SNAPSHOT); - exit(0); - } else if (matches(opt, "-force") == 0) { - ++force; - } else if (matches(opt, "-batch") == 0) { - argc--; - argv++; - if (argc <= 1) - usage(); - batch_file = argv[1]; - } else if (matches(opt, "-help") == 0) { - usage(); - } else { - fprintf(stderr, "Option \"%s\" is unknown, try \"ip -help\".\n", opt); - exit(-1); - } - argc--; argv++; - } - - _SL_ = oneline ? "\\" : "\n" ; - - if (batch_file) - return batch(batch_file); - - if (rtnl_open(&rth, 0) < 0) - exit(1); - - if (strlen(basename) > 2) - return do_cmd(basename+2, argc, argv); - - if (argc > 1) - return do_cmd(argv[1], argc-1, argv+1); - - rtnl_close(&rth); - usage(); -} diff --git a/ip/ip_common.h b/ip/ip_common.h deleted file mode 100644 index 1fe4a69..0000000 --- a/ip/ip_common.h +++ /dev/null @@ -1,35 +0,0 @@ -extern int print_linkinfo(const struct sockaddr_nl *who, - struct nlmsghdr *n, - void *arg); -extern int print_addrinfo(const struct sockaddr_nl *who, - struct nlmsghdr *n, - void *arg); -extern int print_neigh(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg); -extern int print_ntable(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg); -extern int ipaddr_list(int argc, char **argv); -extern int ipaddr_list_link(int argc, char **argv); -extern int iproute_monitor(int argc, char **argv); -extern void iplink_usage(void) __attribute__((noreturn)); -extern void iproute_reset_filter(void); -extern void ipaddr_reset_filter(int); -extern void ipneigh_reset_filter(void); -extern void ipntable_reset_filter(void); -extern int print_route(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg); -extern int print_prefix(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg); -extern int do_ipaddr(int argc, char **argv); -extern int do_iproute(int argc, char **argv); -extern int do_iprule(int argc, char **argv); -extern int do_ipneigh(int argc, char **argv); -extern int do_ipntable(int argc, char **argv); -extern int do_iptunnel(int argc, char **argv); -extern int do_iplink(int argc, char **argv); -extern int do_ipmonitor(int argc, char **argv); -extern int do_multiaddr(int argc, char **argv); -extern int do_multiroute(int argc, char **argv); -extern int do_xfrm(int argc, char **argv); - -extern struct rtnl_handle rth; diff --git a/ip/ipaddress.c b/ip/ipaddress.c deleted file mode 100644 index cb164c0..0000000 --- a/ip/ipaddress.c +++ /dev/null @@ -1,907 +0,0 @@ -/* - * ipaddress.c "ip address". - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - * Changes: - * Laszlo Valko <valko@linux.karinthy.hu> 990223: address label must be zero terminated - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <fnmatch.h> - -#include <linux/netdevice.h> -#include <linux/if_arp.h> -#include <linux/sockios.h> - -#include "rt_names.h" -#include "utils.h" -#include "ll_map.h" -#include "ip_common.h" - -static struct -{ - int ifindex; - int family; - int oneline; - int showqueue; - inet_prefix pfx; - int scope, scopemask; - int flags, flagmask; - int up; - char *label; - int flushed; - char *flushb; - int flushp; - int flushe; -} filter; - -static int do_link; - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - if (do_link) { - iplink_usage(); - } - fprintf(stderr, "Usage: ip addr {add|del} IFADDR dev STRING\n"); - fprintf(stderr, " ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n"); - fprintf(stderr, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n"); - fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n"); - fprintf(stderr, " [ broadcast ADDR ] [ anycast ADDR ]\n"); - fprintf(stderr, " [ label STRING ] [ scope SCOPE-ID ]\n"); - fprintf(stderr, "SCOPE-ID := [ host | link | global | NUMBER ]\n"); - fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n"); - fprintf(stderr, "FLAG := [ permanent | dynamic | secondary | primary |\n"); - fprintf(stderr, " tentative | deprecated ]\n"); - exit(-1); -} - -void print_link_flags(FILE *fp, unsigned flags, unsigned mdown) -{ - fprintf(fp, "<"); - if (flags & IFF_UP && !(flags & IFF_RUNNING)) - fprintf(fp, "NO-CARRIER%s", flags ? "," : ""); - flags &= ~IFF_RUNNING; -#define _PF(f) if (flags&IFF_##f) { \ - flags &= ~IFF_##f ; \ - fprintf(fp, #f "%s", flags ? "," : ""); } - _PF(LOOPBACK); - _PF(BROADCAST); - _PF(POINTOPOINT); - _PF(MULTICAST); - _PF(NOARP); - _PF(ALLMULTI); - _PF(PROMISC); - _PF(MASTER); - _PF(SLAVE); - _PF(DEBUG); - _PF(DYNAMIC); - _PF(AUTOMEDIA); - _PF(PORTSEL); - _PF(NOTRAILERS); - _PF(UP); -#undef _PF - if (flags) - fprintf(fp, "%x", flags); - if (mdown) - fprintf(fp, ",M-DOWN"); - fprintf(fp, "> "); -} - -void print_queuelen(char *name) -{ - struct ifreq ifr; - int s; - - s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) - return; - - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, name); - if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) { - perror("SIOCGIFXQLEN"); - close(s); - return; - } - close(s); - - if (ifr.ifr_qlen) - printf("qlen %d", ifr.ifr_qlen); -} - -int print_linkinfo(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg) -{ - FILE *fp = (FILE*)arg; - struct ifinfomsg *ifi = NLMSG_DATA(n); - struct rtattr * tb[IFLA_MAX+1]; - int len = n->nlmsg_len; - unsigned m_flag = 0; - - if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) - return 0; - - len -= NLMSG_LENGTH(sizeof(*ifi)); - if (len < 0) - return -1; - - if (filter.ifindex && ifi->ifi_index != filter.ifindex) - return 0; - if (filter.up && !(ifi->ifi_flags&IFF_UP)) - return 0; - - parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); - if (tb[IFLA_IFNAME] == NULL) { - fprintf(stderr, "BUG: nil ifname\n"); - return -1; - } - if (filter.label && - (!filter.family || filter.family == AF_PACKET) && - fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) - return 0; - - if (n->nlmsg_type == RTM_DELLINK) - fprintf(fp, "Deleted "); - - fprintf(fp, "%d: %s", ifi->ifi_index, - tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>"); - - if (tb[IFLA_LINK]) { - SPRINT_BUF(b1); - int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); - if (iflink == 0) - fprintf(fp, "@NONE: "); - else { - fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1)); - m_flag = ll_index_to_flags(iflink); - m_flag = !(m_flag & IFF_UP); - } - } else { - fprintf(fp, ": "); - } - print_link_flags(fp, ifi->ifi_flags, m_flag); - - if (tb[IFLA_MTU]) - fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); - if (tb[IFLA_QDISC]) - fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); -#ifdef IFLA_MASTER - if (tb[IFLA_MASTER]) { - SPRINT_BUF(b1); - fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); - } -#endif - if (filter.showqueue) - print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME])); - - if (!filter.family || filter.family == AF_PACKET) { - SPRINT_BUF(b1); - fprintf(fp, "%s", _SL_); - fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); - - if (tb[IFLA_ADDRESS]) { - fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), - RTA_PAYLOAD(tb[IFLA_ADDRESS]), - ifi->ifi_type, - b1, sizeof(b1))); - } - if (tb[IFLA_BROADCAST]) { - if (ifi->ifi_flags&IFF_POINTOPOINT) - fprintf(fp, " peer "); - else - fprintf(fp, " brd "); - fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]), - RTA_PAYLOAD(tb[IFLA_BROADCAST]), - ifi->ifi_type, - b1, sizeof(b1))); - } - } - if (do_link && tb[IFLA_STATS] && show_stats) { - struct rtnl_link_stats slocal; - struct rtnl_link_stats *s = RTA_DATA(tb[IFLA_STATS]); - if (((unsigned long)s) & (sizeof(unsigned long)-1)) { - memcpy(&slocal, s, sizeof(slocal)); - s = &slocal; - } - fprintf(fp, "%s", _SL_); - fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", - s->rx_compressed ? "compressed" : "", _SL_); - fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", - s->rx_bytes, s->rx_packets, s->rx_errors, - s->rx_dropped, s->rx_over_errors, - s->multicast - ); - if (s->rx_compressed) - fprintf(fp, " %-7u", s->rx_compressed); - if (show_stats > 1) { - fprintf(fp, "%s", _SL_); - fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_); - fprintf(fp, " %-7u %-7u %-7u %-7u %-7u", - s->rx_length_errors, - s->rx_crc_errors, - s->rx_frame_errors, - s->rx_fifo_errors, - s->rx_missed_errors - ); - } - fprintf(fp, "%s", _SL_); - fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", - s->tx_compressed ? "compressed" : "", _SL_); - fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", - s->tx_bytes, s->tx_packets, s->tx_errors, - s->tx_dropped, s->tx_carrier_errors, s->collisions); - if (s->tx_compressed) - fprintf(fp, " %-7u", s->tx_compressed); - if (show_stats > 1) { - fprintf(fp, "%s", _SL_); - fprintf(fp, " TX errors: aborted fifo window heartbeat%s", _SL_); - fprintf(fp, " %-7u %-7u %-7u %-7u", - s->tx_aborted_errors, - s->tx_fifo_errors, - s->tx_window_errors, - s->tx_heartbeat_errors - ); - } - } - fprintf(fp, "\n"); - fflush(fp); - return 0; -} - -static int flush_update(void) -{ - if (rtnl_send(&rth, filter.flushb, filter.flushp) < 0) { - perror("Failed to send flush request\n"); - return -1; - } - filter.flushp = 0; - return 0; -} - -int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, - void *arg) -{ - FILE *fp = (FILE*)arg; - struct ifaddrmsg *ifa = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr * rta_tb[IFA_MAX+1]; - char abuf[256]; - SPRINT_BUF(b1); - - if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) - return 0; - len -= NLMSG_LENGTH(sizeof(*ifa)); - if (len < 0) { - fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); - return -1; - } - - if (filter.flushb && n->nlmsg_type != RTM_NEWADDR) - return 0; - - parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); - - if (!rta_tb[IFA_LOCAL]) - rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; - if (!rta_tb[IFA_ADDRESS]) - rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL]; - - if (filter.ifindex && filter.ifindex != ifa->ifa_index) - return 0; - if ((filter.scope^ifa->ifa_scope)&filter.scopemask) - return 0; - if ((filter.flags^ifa->ifa_flags)&filter.flagmask) - return 0; - if (filter.label) { - SPRINT_BUF(b1); - const char *label; - if (rta_tb[IFA_LABEL]) - label = RTA_DATA(rta_tb[IFA_LABEL]); - else - label = ll_idx_n2a(ifa->ifa_index, b1); - if (fnmatch(filter.label, label, 0) != 0) - return 0; - } - if (filter.pfx.family) { - if (rta_tb[IFA_LOCAL]) { - inet_prefix dst; - memset(&dst, 0, sizeof(dst)); - dst.family = ifa->ifa_family; - memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL])); - if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) - return 0; - } - } - - if (filter.family && filter.family != ifa->ifa_family) - return 0; - - if (filter.flushb) { - struct nlmsghdr *fn; - if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { - if (flush_update()) - return -1; - } - fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); - memcpy(fn, n, n->nlmsg_len); - fn->nlmsg_type = RTM_DELADDR; - fn->nlmsg_flags = NLM_F_REQUEST; - fn->nlmsg_seq = ++rth.seq; - filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb; - filter.flushed++; - if (show_stats < 2) - return 0; - } - - if (n->nlmsg_type == RTM_DELADDR) - fprintf(fp, "Deleted "); - - if (filter.oneline || filter.flushb) - fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index)); - if (ifa->ifa_family == AF_INET) - fprintf(fp, " inet "); - else if (ifa->ifa_family == AF_INET6) - fprintf(fp, " inet6 "); - else if (ifa->ifa_family == AF_DECnet) - fprintf(fp, " dnet "); - else if (ifa->ifa_family == AF_IPX) - fprintf(fp, " ipx "); - else - fprintf(fp, " family %d ", ifa->ifa_family); - - if (rta_tb[IFA_LOCAL]) { - fprintf(fp, "%s", rt_addr_n2a(ifa->ifa_family, - RTA_PAYLOAD(rta_tb[IFA_LOCAL]), - RTA_DATA(rta_tb[IFA_LOCAL]), - abuf, sizeof(abuf))); - - if (rta_tb[IFA_ADDRESS] == NULL || - memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0) { - fprintf(fp, "/%d ", ifa->ifa_prefixlen); - } else { - fprintf(fp, " peer %s/%d ", - rt_addr_n2a(ifa->ifa_family, - RTA_PAYLOAD(rta_tb[IFA_ADDRESS]), - RTA_DATA(rta_tb[IFA_ADDRESS]), - abuf, sizeof(abuf)), - ifa->ifa_prefixlen); - } - } - - if (rta_tb[IFA_BROADCAST]) { - fprintf(fp, "brd %s ", - rt_addr_n2a(ifa->ifa_family, - RTA_PAYLOAD(rta_tb[IFA_BROADCAST]), - RTA_DATA(rta_tb[IFA_BROADCAST]), - abuf, sizeof(abuf))); - } - if (rta_tb[IFA_ANYCAST]) { - fprintf(fp, "any %s ", - rt_addr_n2a(ifa->ifa_family, - RTA_PAYLOAD(rta_tb[IFA_ANYCAST]), - RTA_DATA(rta_tb[IFA_ANYCAST]), - abuf, sizeof(abuf))); - } - fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1))); - if (ifa->ifa_flags&IFA_F_SECONDARY) { - ifa->ifa_flags &= ~IFA_F_SECONDARY; - fprintf(fp, "secondary "); - } - if (ifa->ifa_flags&IFA_F_TENTATIVE) { - ifa->ifa_flags &= ~IFA_F_TENTATIVE; - fprintf(fp, "tentative "); - } - if (ifa->ifa_flags&IFA_F_DEPRECATED) { - ifa->ifa_flags &= ~IFA_F_DEPRECATED; - fprintf(fp, "deprecated "); - } - if (!(ifa->ifa_flags&IFA_F_PERMANENT)) { - fprintf(fp, "dynamic "); - } else - ifa->ifa_flags &= ~IFA_F_PERMANENT; - if (ifa->ifa_flags) - fprintf(fp, "flags %02x ", ifa->ifa_flags); - if (rta_tb[IFA_LABEL]) - fprintf(fp, "%s", (char*)RTA_DATA(rta_tb[IFA_LABEL])); - if (rta_tb[IFA_CACHEINFO]) { - struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]); - char buf[128]; - fprintf(fp, "%s", _SL_); - if (ci->ifa_valid == 0xFFFFFFFFU) - sprintf(buf, "valid_lft forever"); - else - sprintf(buf, "valid_lft %dsec", ci->ifa_valid); - if (ci->ifa_prefered == 0xFFFFFFFFU) - sprintf(buf+strlen(buf), " preferred_lft forever"); - else - sprintf(buf+strlen(buf), " preferred_lft %dsec", ci->ifa_prefered); - fprintf(fp, " %s", buf); - } - fprintf(fp, "\n"); - fflush(fp); - return 0; -} - - -struct nlmsg_list -{ - struct nlmsg_list *next; - struct nlmsghdr h; -}; - -int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp) -{ - for ( ;ainfo ; ainfo = ainfo->next) { - struct nlmsghdr *n = &ainfo->h; - struct ifaddrmsg *ifa = NLMSG_DATA(n); - - if (n->nlmsg_type != RTM_NEWADDR) - continue; - - if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa))) - return -1; - - if (ifa->ifa_index != ifindex || - (filter.family && filter.family != ifa->ifa_family)) - continue; - - print_addrinfo(NULL, n, fp); - } - return 0; -} - - -static int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, - void *arg) -{ - struct nlmsg_list **linfo = (struct nlmsg_list**)arg; - struct nlmsg_list *h; - struct nlmsg_list **lp; - - h = malloc(n->nlmsg_len+sizeof(void*)); - if (h == NULL) - return -1; - - memcpy(&h->h, n, n->nlmsg_len); - h->next = NULL; - - for (lp = linfo; *lp; lp = &(*lp)->next) /* NOTHING */; - *lp = h; - - ll_remember_index(who, n, NULL); - return 0; -} - -int ipaddr_list_or_flush(int argc, char **argv, int flush) -{ - struct nlmsg_list *linfo = NULL; - struct nlmsg_list *ainfo = NULL; - struct nlmsg_list *l, *n; - char *filter_dev = NULL; - int no_link = 0; - - ipaddr_reset_filter(oneline); - filter.showqueue = 1; - - if (filter.family == AF_UNSPEC) - filter.family = preferred_family; - - if (flush) { - if (argc <= 0) { - fprintf(stderr, "Flush requires arguments.\n"); - return -1; - } - if (filter.family == AF_PACKET) { - fprintf(stderr, "Cannot flush link addresses.\n"); - return -1; - } - } - - while (argc > 0) { - if (strcmp(*argv, "to") == 0) { - NEXT_ARG(); - get_prefix(&filter.pfx, *argv, filter.family); - if (filter.family == AF_UNSPEC) - filter.family = filter.pfx.family; - } else if (strcmp(*argv, "scope") == 0) { - unsigned scope = 0; - NEXT_ARG(); - filter.scopemask = -1; - if (rtnl_rtscope_a2n(&scope, *argv)) { - if (strcmp(*argv, "all") != 0) - invarg("invalid \"scope\"\n", *argv); - scope = RT_SCOPE_NOWHERE; - filter.scopemask = 0; - } - filter.scope = scope; - } else if (strcmp(*argv, "up") == 0) { - filter.up = 1; - } else if (strcmp(*argv, "dynamic") == 0) { - filter.flags &= ~IFA_F_PERMANENT; - filter.flagmask |= IFA_F_PERMANENT; - } else if (strcmp(*argv, "permanent") == 0) { - filter.flags |= IFA_F_PERMANENT; - filter.flagmask |= IFA_F_PERMANENT; - } else if (strcmp(*argv, "secondary") == 0) { - filter.flags |= IFA_F_SECONDARY; - filter.flagmask |= IFA_F_SECONDARY; - } else if (strcmp(*argv, "primary") == 0) { - filter.flags &= ~IFA_F_SECONDARY; - filter.flagmask |= IFA_F_SECONDARY; - } else if (strcmp(*argv, "tentative") == 0) { - filter.flags |= IFA_F_TENTATIVE; - filter.flagmask |= IFA_F_TENTATIVE; - } else if (strcmp(*argv, "deprecated") == 0) { - filter.flags |= IFA_F_DEPRECATED; - filter.flagmask |= IFA_F_DEPRECATED; - } else if (strcmp(*argv, "label") == 0) { - NEXT_ARG(); - filter.label = *argv; - } else { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "help") == 0) - usage(); - if (filter_dev) - duparg2("dev", *argv); - filter_dev = *argv; - } - argv++; argc--; - } - - if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) { - perror("Cannot send dump request"); - exit(1); - } - - if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - exit(1); - } - - if (filter_dev) { - filter.ifindex = ll_name_to_index(filter_dev); - if (filter.ifindex <= 0) { - fprintf(stderr, "Device \"%s\" does not exist.\n", filter_dev); - return -1; - } - } - - if (flush) { - int round = 0; - char flushb[4096-512]; - - filter.flushb = flushb; - filter.flushp = 0; - filter.flushe = sizeof(flushb); - - for (;;) { - if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { - perror("Cannot send dump request"); - exit(1); - } - filter.flushed = 0; - if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Flush terminated\n"); - exit(1); - } - if (filter.flushed == 0) { - if (round == 0) { - fprintf(stderr, "Nothing to flush.\n"); - } else if (show_stats) - printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":""); - fflush(stdout); - return 0; - } - round++; - if (flush_update() < 0) - return 1; - - if (show_stats) { - printf("\n*** Round %d, deleting %d addresses ***\n", round, filter.flushed); - fflush(stdout); - } - } - } - - if (filter.family != AF_PACKET) { - if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { - perror("Cannot send dump request"); - exit(1); - } - - if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - exit(1); - } - } - - - if (filter.family && filter.family != AF_PACKET) { - struct nlmsg_list **lp; - lp=&linfo; - - if (filter.oneline) - no_link = 1; - - while ((l=*lp)!=NULL) { - int ok = 0; - struct ifinfomsg *ifi = NLMSG_DATA(&l->h); - struct nlmsg_list *a; - - for (a=ainfo; a; a=a->next) { - struct nlmsghdr *n = &a->h; - struct ifaddrmsg *ifa = NLMSG_DATA(n); - - if (ifa->ifa_index != ifi->ifi_index || - (filter.family && filter.family != ifa->ifa_family)) - continue; - if ((filter.scope^ifa->ifa_scope)&filter.scopemask) - continue; - if ((filter.flags^ifa->ifa_flags)&filter.flagmask) - continue; - if (filter.pfx.family || filter.label) { - struct rtattr *tb[IFA_MAX+1]; - parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n)); - if (!tb[IFA_LOCAL]) - tb[IFA_LOCAL] = tb[IFA_ADDRESS]; - - if (filter.pfx.family && tb[IFA_LOCAL]) { - inet_prefix dst; - memset(&dst, 0, sizeof(dst)); - dst.family = ifa->ifa_family; - memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL])); - if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) - continue; - } - if (filter.label) { - SPRINT_BUF(b1); - const char *label; - if (tb[IFA_LABEL]) - label = RTA_DATA(tb[IFA_LABEL]); - else - label = ll_idx_n2a(ifa->ifa_index, b1); - if (fnmatch(filter.label, label, 0) != 0) - continue; - } - } - - ok = 1; - break; - } - if (!ok) - *lp = l->next; - else - lp = &l->next; - } - } - - for (l=linfo; l; l = n) { - n = l->next; - if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) { - struct ifinfomsg *ifi = NLMSG_DATA(&l->h); - if (filter.family != AF_PACKET) - print_selected_addrinfo(ifi->ifi_index, ainfo, stdout); - } - fflush(stdout); - free(l); - } - - return 0; -} - -int ipaddr_list_link(int argc, char **argv) -{ - preferred_family = AF_PACKET; - do_link = 1; - return ipaddr_list_or_flush(argc, argv, 0); -} - -void ipaddr_reset_filter(int oneline) -{ - memset(&filter, 0, sizeof(filter)); - filter.oneline = oneline; -} - -int default_scope(inet_prefix *lcl) -{ - if (lcl->family == AF_INET) { - if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127) - return RT_SCOPE_HOST; - } - return 0; -} - -int ipaddr_modify(int cmd, int argc, char **argv) -{ - struct { - struct nlmsghdr n; - struct ifaddrmsg ifa; - char buf[256]; - } req; - char *d = NULL; - char *l = NULL; - char *lcl_arg = NULL; - inet_prefix lcl; - inet_prefix peer; - int local_len = 0; - int peer_len = 0; - int brd_len = 0; - int any_len = 0; - int scoped = 0; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST; - req.n.nlmsg_type = cmd; - req.ifa.ifa_family = preferred_family; - - while (argc > 0) { - if (strcmp(*argv, "peer") == 0 || - strcmp(*argv, "remote") == 0) { - NEXT_ARG(); - - if (peer_len) - duparg("peer", *argv); - get_prefix(&peer, *argv, req.ifa.ifa_family); - peer_len = peer.bytelen; - if (req.ifa.ifa_family == AF_UNSPEC) - req.ifa.ifa_family = peer.family; - addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen); - req.ifa.ifa_prefixlen = peer.bitlen; - } else if (matches(*argv, "broadcast") == 0 || - strcmp(*argv, "brd") == 0) { - inet_prefix addr; - NEXT_ARG(); - if (brd_len) - duparg("broadcast", *argv); - if (strcmp(*argv, "+") == 0) - brd_len = -1; - else if (strcmp(*argv, "-") == 0) - brd_len = -2; - else { - get_addr(&addr, *argv, req.ifa.ifa_family); - if (req.ifa.ifa_family == AF_UNSPEC) - req.ifa.ifa_family = addr.family; - addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen); - brd_len = addr.bytelen; - } - } else if (strcmp(*argv, "anycast") == 0) { - inet_prefix addr; - NEXT_ARG(); - if (any_len) - duparg("anycast", *argv); - get_addr(&addr, *argv, req.ifa.ifa_family); - if (req.ifa.ifa_family == AF_UNSPEC) - req.ifa.ifa_family = addr.family; - addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); - any_len = addr.bytelen; - } else if (strcmp(*argv, "scope") == 0) { - unsigned scope = 0; - NEXT_ARG(); - if (rtnl_rtscope_a2n(&scope, *argv)) - invarg(*argv, "invalid scope value."); - req.ifa.ifa_scope = scope; - scoped = 1; - } else if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - d = *argv; - } else if (strcmp(*argv, "label") == 0) { - NEXT_ARG(); - l = *argv; - addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1); - } else { - if (strcmp(*argv, "local") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "help") == 0) - usage(); - if (local_len) - duparg2("local", *argv); - lcl_arg = *argv; - get_prefix(&lcl, *argv, req.ifa.ifa_family); - if (req.ifa.ifa_family == AF_UNSPEC) - req.ifa.ifa_family = lcl.family; - addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); - local_len = lcl.bytelen; - } - argc--; argv++; - } - if (d == NULL) { - fprintf(stderr, "Not enough information: \"dev\" argument is required.\n"); - return -1; - } - if (l && matches(d, l) != 0) { - fprintf(stderr, "\"dev\" (%s) must match \"label\" (%s).\n", d, l); - exit(1); - } - - if (peer_len == 0 && local_len) { - if (cmd == RTM_DELADDR && lcl.family == AF_INET && !(lcl.flags & PREFIXLEN_SPECIFIED)) { - fprintf(stderr, - "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \ - " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \ - " This special behaviour is likely to disappear in further releases,\n" \ - " fix your scripts!\n", lcl_arg, local_len*8); - } else { - peer = lcl; - addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen); - } - } - if (req.ifa.ifa_prefixlen == 0) - req.ifa.ifa_prefixlen = lcl.bitlen; - - if (brd_len < 0 && cmd != RTM_DELADDR) { - inet_prefix brd; - int i; - if (req.ifa.ifa_family != AF_INET) { - fprintf(stderr, "Broadcast can be set only for IPv4 addresses\n"); - return -1; - } - brd = peer; - if (brd.bitlen <= 30) { - for (i=31; i>=brd.bitlen; i--) { - if (brd_len == -1) - brd.data[0] |= htonl(1<<(31-i)); - else - brd.data[0] &= ~htonl(1<<(31-i)); - } - addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &brd.data, brd.bytelen); - brd_len = brd.bytelen; - } - } - if (!scoped && cmd != RTM_DELADDR) - req.ifa.ifa_scope = default_scope(&lcl); - - ll_init_map(&rth); - - if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return -1; - } - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - exit(2); - - return 0; -} - -int do_ipaddr(int argc, char **argv) -{ - if (argc < 1) - return ipaddr_list_or_flush(0, NULL, 0); - if (matches(*argv, "add") == 0) - return ipaddr_modify(RTM_NEWADDR, argc-1, argv+1); - if (matches(*argv, "delete") == 0) - return ipaddr_modify(RTM_DELADDR, argc-1, argv+1); - if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 - || matches(*argv, "lst") == 0) - return ipaddr_list_or_flush(argc-1, argv+1, 0); - if (matches(*argv, "flush") == 0) - return ipaddr_list_or_flush(argc-1, argv+1, 1); - if (matches(*argv, "help") == 0) - usage(); - fprintf(stderr, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv); - exit(-1); -} - diff --git a/ip/iplink.c b/ip/iplink.c deleted file mode 100644 index ffc9f06..0000000 --- a/ip/iplink.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * iplink.c "ip link". - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/socket.h> -#include <linux/if.h> -#include <linux/if_packet.h> -#include <linux/if_ether.h> -#include <linux/sockios.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <sys/ioctl.h> -#include <linux/sockios.h> - -#include "rt_names.h" -#include "utils.h" -#include "ip_common.h" - - -static void usage(void) __attribute__((noreturn)); - -void iplink_usage(void) -{ - fprintf(stderr, "Usage: ip link set DEVICE { up | down |\n"); - fprintf(stderr, " arp { on | off } |\n"); - fprintf(stderr, " dynamic { on | off } |\n"); - fprintf(stderr, " multicast { on | off } |\n"); - fprintf(stderr, " allmulticast { on | off } |\n"); - fprintf(stderr, " promisc { on | off } |\n"); - fprintf(stderr, " trailers { on | off } |\n"); - fprintf(stderr, " txqueuelen PACKETS |\n"); - fprintf(stderr, " name NEWNAME |\n"); - fprintf(stderr, " address LLADDR | broadcast LLADDR |\n"); - fprintf(stderr, " mtu MTU }\n"); - fprintf(stderr, " ip link show [ DEVICE ]\n"); - exit(-1); -} - -static void usage(void) -{ - iplink_usage(); -} - -static int on_off(char *msg) -{ - fprintf(stderr, "Error: argument of \"%s\" must be \"on\" or \"off\"\n", msg); - return -1; -} - -static int get_ctl_fd(void) -{ - int s_errno; - int fd; - - fd = socket(PF_INET, SOCK_DGRAM, 0); - if (fd >= 0) - return fd; - s_errno = errno; - fd = socket(PF_PACKET, SOCK_DGRAM, 0); - if (fd >= 0) - return fd; - fd = socket(PF_INET6, SOCK_DGRAM, 0); - if (fd >= 0) - return fd; - errno = s_errno; - perror("Cannot create control socket"); - return -1; -} - -static int do_chflags(const char *dev, __u32 flags, __u32 mask) -{ - struct ifreq ifr; - int fd; - int err; - - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - fd = get_ctl_fd(); - if (fd < 0) - return -1; - err = ioctl(fd, SIOCGIFFLAGS, &ifr); - if (err) { - perror("SIOCGIFFLAGS"); - close(fd); - return -1; - } - if ((ifr.ifr_flags^flags)&mask) { - ifr.ifr_flags &= ~mask; - ifr.ifr_flags |= mask&flags; - err = ioctl(fd, SIOCSIFFLAGS, &ifr); - if (err) - perror("SIOCSIFFLAGS"); - } - close(fd); - return err; -} - -static int do_changename(const char *dev, const char *newdev) -{ - struct ifreq ifr; - int fd; - int err; - - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - strncpy(ifr.ifr_newname, newdev, IFNAMSIZ); - fd = get_ctl_fd(); - if (fd < 0) - return -1; - err = ioctl(fd, SIOCSIFNAME, &ifr); - if (err) { - perror("SIOCSIFNAME"); - close(fd); - return -1; - } - close(fd); - return err; -} - -static int set_qlen(const char *dev, int qlen) -{ - struct ifreq ifr; - int s; - - s = get_ctl_fd(); - if (s < 0) - return -1; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - ifr.ifr_qlen = qlen; - if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) { - perror("SIOCSIFXQLEN"); - close(s); - return -1; - } - close(s); - - return 0; -} - -static int set_mtu(const char *dev, int mtu) -{ - struct ifreq ifr; - int s; - - s = get_ctl_fd(); - if (s < 0) - return -1; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - ifr.ifr_mtu = mtu; - if (ioctl(s, SIOCSIFMTU, &ifr) < 0) { - perror("SIOCSIFMTU"); - close(s); - return -1; - } - close(s); - - return 0; -} - -static int get_address(const char *dev, int *htype) -{ - struct ifreq ifr; - struct sockaddr_ll me; - socklen_t alen; - int s; - - s = socket(PF_PACKET, SOCK_DGRAM, 0); - if (s < 0) { - perror("socket(PF_PACKET)"); - return -1; - } - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { - perror("SIOCGIFINDEX"); - close(s); - return -1; - } - - memset(&me, 0, sizeof(me)); - me.sll_family = AF_PACKET; - me.sll_ifindex = ifr.ifr_ifindex; - me.sll_protocol = htons(ETH_P_LOOP); - if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { - perror("bind"); - close(s); - return -1; - } - - alen = sizeof(me); - if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { - perror("getsockname"); - close(s); - return -1; - } - close(s); - *htype = me.sll_hatype; - return me.sll_halen; -} - -static int parse_address(const char *dev, int hatype, int halen, - char *lla, struct ifreq *ifr) -{ - int alen; - - memset(ifr, 0, sizeof(*ifr)); - strncpy(ifr->ifr_name, dev, IFNAMSIZ); - ifr->ifr_hwaddr.sa_family = hatype; - alen = ll_addr_a2n(ifr->ifr_hwaddr.sa_data, 14, lla); - if (alen < 0) - return -1; - if (alen != halen) { - fprintf(stderr, "Wrong address (%s) length: expected %d bytes\n", lla, halen); - return -1; - } - return 0; -} - -static int set_address(struct ifreq *ifr, int brd) -{ - int s; - - s = get_ctl_fd(); - if (s < 0) - return -1; - if (ioctl(s, brd?SIOCSIFHWBROADCAST:SIOCSIFHWADDR, ifr) < 0) { - perror(brd?"SIOCSIFHWBROADCAST":"SIOCSIFHWADDR"); - close(s); - return -1; - } - close(s); - return 0; -} - - -static int do_set(int argc, char **argv) -{ - char *dev = NULL; - __u32 mask = 0; - __u32 flags = 0; - int qlen = -1; - int mtu = -1; - char *newaddr = NULL; - char *newbrd = NULL; - struct ifreq ifr0, ifr1; - char *newname = NULL; - int htype, halen; - - while (argc > 0) { - if (strcmp(*argv, "up") == 0) { - mask |= IFF_UP; - flags |= IFF_UP; - } else if (strcmp(*argv, "down") == 0) { - mask |= IFF_UP; - flags &= ~IFF_UP; - } else if (strcmp(*argv, "name") == 0) { - NEXT_ARG(); - newname = *argv; - } else if (matches(*argv, "address") == 0) { - NEXT_ARG(); - newaddr = *argv; - } else if (matches(*argv, "broadcast") == 0 || - strcmp(*argv, "brd") == 0) { - NEXT_ARG(); - newbrd = *argv; - } else if (matches(*argv, "txqueuelen") == 0 || - strcmp(*argv, "qlen") == 0 || - matches(*argv, "txqlen") == 0) { - NEXT_ARG(); - if (qlen != -1) - duparg("txqueuelen", *argv); - if (get_integer(&qlen, *argv, 0)) - invarg("Invalid \"txqueuelen\" value\n", *argv); - } else if (strcmp(*argv, "mtu") == 0) { - NEXT_ARG(); - if (mtu != -1) - duparg("mtu", *argv); - if (get_integer(&mtu, *argv, 0)) - invarg("Invalid \"mtu\" value\n", *argv); - } else if (strcmp(*argv, "multicast") == 0) { - NEXT_ARG(); - mask |= IFF_MULTICAST; - if (strcmp(*argv, "on") == 0) { - flags |= IFF_MULTICAST; - } else if (strcmp(*argv, "off") == 0) { - flags &= ~IFF_MULTICAST; - } else - return on_off("multicast"); - } else if (strcmp(*argv, "allmulticast") == 0) { - NEXT_ARG(); - mask |= IFF_ALLMULTI; - if (strcmp(*argv, "on") == 0) { - flags |= IFF_ALLMULTI; - } else if (strcmp(*argv, "off") == 0) { - flags &= ~IFF_ALLMULTI; - } else - return on_off("allmulticast"); - } else if (strcmp(*argv, "promisc") == 0) { - NEXT_ARG(); - mask |= IFF_PROMISC; - if (strcmp(*argv, "on") == 0) { - flags |= IFF_PROMISC; - } else if (strcmp(*argv, "off") == 0) { - flags &= ~IFF_PROMISC; - } else - return on_off("promisc"); - } else if (strcmp(*argv, "trailers") == 0) { - NEXT_ARG(); - mask |= IFF_NOTRAILERS; - if (strcmp(*argv, "off") == 0) { - flags |= IFF_NOTRAILERS; - } else if (strcmp(*argv, "on") == 0) { - flags &= ~IFF_NOTRAILERS; - } else - return on_off("trailers"); - } else if (strcmp(*argv, "arp") == 0) { - NEXT_ARG(); - mask |= IFF_NOARP; - if (strcmp(*argv, "on") == 0) { - flags &= ~IFF_NOARP; - } else if (strcmp(*argv, "off") == 0) { - flags |= IFF_NOARP; - } else - return on_off("noarp"); -#ifdef IFF_DYNAMIC - } else if (matches(*argv, "dynamic") == 0) { - NEXT_ARG(); - mask |= IFF_DYNAMIC; - if (strcmp(*argv, "on") == 0) { - flags |= IFF_DYNAMIC; - } else if (strcmp(*argv, "off") == 0) { - flags &= ~IFF_DYNAMIC; - } else - return on_off("dynamic"); -#endif - } else { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "help") == 0) - usage(); - if (dev) - duparg2("dev", *argv); - dev = *argv; - } - argc--; argv++; - } - - if (!dev) { - fprintf(stderr, "Not enough of information: \"dev\" argument is required.\n"); - exit(-1); - } - - if (newaddr || newbrd) { - halen = get_address(dev, &htype); - if (halen < 0) - return -1; - if (newaddr) { - if (parse_address(dev, htype, halen, newaddr, &ifr0) < 0) - return -1; - } - if (newbrd) { - if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0) - return -1; - } - } - - if (newname && strcmp(dev, newname)) { - if (do_changename(dev, newname) < 0) - return -1; - dev = newname; - } - if (qlen != -1) { - if (set_qlen(dev, qlen) < 0) - return -1; - } - if (mtu != -1) { - if (set_mtu(dev, mtu) < 0) - return -1; - } - if (newaddr || newbrd) { - if (newbrd) { - if (set_address(&ifr1, 1) < 0) - return -1; - } - if (newaddr) { - if (set_address(&ifr0, 0) < 0) - return -1; - } - } - if (mask) - return do_chflags(dev, flags, mask); - return 0; -} - -int do_iplink(int argc, char **argv) -{ - if (argc > 0) { - if (matches(*argv, "set") == 0) - return do_set(argc-1, argv+1); - if (matches(*argv, "show") == 0 || - matches(*argv, "lst") == 0 || - matches(*argv, "list") == 0) - return ipaddr_list_link(argc-1, argv+1); - if (matches(*argv, "help") == 0) - usage(); - } else - return ipaddr_list_link(0, NULL); - - fprintf(stderr, "Command \"%s\" is unknown, try \"ip link help\".\n", *argv); - exit(-1); -} diff --git a/ip/ipmaddr.c b/ip/ipmaddr.c deleted file mode 100644 index e6bd625..0000000 --- a/ip/ipmaddr.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * ipmaddr.c "ip maddress". - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include <linux/netdevice.h> -#include <linux/if.h> -#include <linux/if_arp.h> -#include <linux/sockios.h> - -#include "rt_names.h" -#include "utils.h" - -static struct { - char *dev; - int family; -} filter; - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, "Usage: ip maddr [ add | del ] MULTIADDR dev STRING\n"); - fprintf(stderr, " ip maddr show [ dev STRING ]\n"); - exit(-1); -} - -static int parse_hex(char *str, unsigned char *addr) -{ - int len=0; - - while (*str) { - int tmp; - if (str[1] == 0) - return -1; - if (sscanf(str, "%02x", &tmp) != 1) - return -1; - addr[len] = tmp; - len++; - str += 2; - } - return len; -} - -struct ma_info -{ - struct ma_info *next; - int index; - int users; - char *features; - char name[IFNAMSIZ]; - inet_prefix addr; -}; - -void maddr_ins(struct ma_info **lst, struct ma_info *m) -{ - struct ma_info *mp; - - for (; (mp=*lst) != NULL; lst = &mp->next) { - if (mp->index > m->index) - break; - } - m->next = *lst; - *lst = m; -} - -void read_dev_mcast(struct ma_info **result_p) -{ - char buf[256]; - FILE *fp = fopen("/proc/net/dev_mcast", "r"); - - if (!fp) - return; - - while (fgets(buf, sizeof(buf), fp)) { - char hexa[256]; - struct ma_info m; - int len; - int st; - - memset(&m, 0, sizeof(m)); - sscanf(buf, "%d%s%d%d%s", &m.index, m.name, &m.users, &st, - hexa); - if (filter.dev && strcmp(filter.dev, m.name)) - continue; - - m.addr.family = AF_PACKET; - - len = parse_hex(hexa, (unsigned char*)&m.addr.data); - if (len >= 0) { - struct ma_info *ma = malloc(sizeof(m)); - - memcpy(ma, &m, sizeof(m)); - ma->addr.bytelen = len; - ma->addr.bitlen = len<<3; - if (st) - ma->features = "static"; - maddr_ins(result_p, ma); - } - } - fclose(fp); -} - -void read_igmp(struct ma_info **result_p) -{ - struct ma_info m; - char buf[256]; - FILE *fp = fopen("/proc/net/igmp", "r"); - - if (!fp) - return; - memset(&m, 0, sizeof(m)); - fgets(buf, sizeof(buf), fp); - - m.addr.family = AF_INET; - m.addr.bitlen = 32; - m.addr.bytelen = 4; - - while (fgets(buf, sizeof(buf), fp)) { - struct ma_info *ma = malloc(sizeof(m)); - - if (buf[0] != '\t') { - sscanf(buf, "%d%s", &m.index, m.name); - continue; - } - - if (filter.dev && strcmp(filter.dev, m.name)) - continue; - - sscanf(buf, "%08x%d", (__u32*)&m.addr.data, &m.users); - - ma = malloc(sizeof(m)); - memcpy(ma, &m, sizeof(m)); - maddr_ins(result_p, ma); - } - fclose(fp); -} - - -void read_igmp6(struct ma_info **result_p) -{ - char buf[256]; - FILE *fp = fopen("/proc/net/igmp6", "r"); - - if (!fp) - return; - - while (fgets(buf, sizeof(buf), fp)) { - char hexa[256]; - struct ma_info m; - int len; - - memset(&m, 0, sizeof(m)); - sscanf(buf, "%d%s%s%d", &m.index, m.name, hexa, &m.users); - - if (filter.dev && strcmp(filter.dev, m.name)) - continue; - - m.addr.family = AF_INET6; - - len = parse_hex(hexa, (unsigned char*)&m.addr.data); - if (len >= 0) { - struct ma_info *ma = malloc(sizeof(m)); - - memcpy(ma, &m, sizeof(m)); - - ma->addr.bytelen = len; - ma->addr.bitlen = len<<3; - maddr_ins(result_p, ma); - } - } - fclose(fp); -} - -static void print_maddr(FILE *fp, struct ma_info *list) -{ - fprintf(fp, "\t"); - - if (list->addr.family == AF_PACKET) { - SPRINT_BUF(b1); - fprintf(fp, "link %s", ll_addr_n2a((unsigned char*)list->addr.data, - list->addr.bytelen, 0, - b1, sizeof(b1))); - } else { - char abuf[256]; - switch(list->addr.family) { - case AF_INET: - fprintf(fp, "inet "); - break; - case AF_INET6: - fprintf(fp, "inet6 "); - break; - default: - fprintf(fp, "family %d ", list->addr.family); - break; - } - fprintf(fp, "%s", - format_host(list->addr.family, - -1, - list->addr.data, - abuf, sizeof(abuf))); - } - if (list->users != 1) - fprintf(fp, " users %d", list->users); - if (list->features) - fprintf(fp, " %s", list->features); - fprintf(fp, "\n"); -} - -static void print_mlist(FILE *fp, struct ma_info *list) -{ - int cur_index = 0; - - for (; list; list = list->next) { - if (oneline) { - cur_index = list->index; - fprintf(fp, "%d:\t%s%s", cur_index, list->name, _SL_); - } else if (cur_index != list->index) { - cur_index = list->index; - fprintf(fp, "%d:\t%s\n", cur_index, list->name); - } - print_maddr(fp, list); - } -} - -static int multiaddr_list(int argc, char **argv) -{ - struct ma_info *list = NULL; - - if (!filter.family) - filter.family = preferred_family; - - while (argc > 0) { - if (1) { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "help") == 0) - usage(); - if (filter.dev) - duparg2("dev", *argv); - filter.dev = *argv; - } - argv++; argc--; - } - - if (!filter.family || filter.family == AF_PACKET) - read_dev_mcast(&list); - if (!filter.family || filter.family == AF_INET) - read_igmp(&list); - if (!filter.family || filter.family == AF_INET6) - read_igmp6(&list); - print_mlist(stdout, list); - return 0; -} - -int multiaddr_modify(int cmd, int argc, char **argv) -{ - struct ifreq ifr; - int fd; - - memset(&ifr, 0, sizeof(ifr)); - - if (cmd == RTM_NEWADDR) - cmd = SIOCADDMULTI; - else - cmd = SIOCDELMULTI; - - while (argc > 0) { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - if (ifr.ifr_name[0]) - duparg("dev", *argv); - strncpy(ifr.ifr_name, *argv, IFNAMSIZ); - } else { - if (matches(*argv, "address") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "help") == 0) - usage(); - if (ifr.ifr_hwaddr.sa_data[0]) - duparg("address", *argv); - if (ll_addr_a2n(ifr.ifr_hwaddr.sa_data, - 14, *argv) < 0) { - fprintf(stderr, "Error: \"%s\" is not a legal ll address.\n", *argv); - exit(1); - } - } - argc--; argv++; - } - if (ifr.ifr_name[0] == 0) { - fprintf(stderr, "Not enough information: \"dev\" is required.\n"); - exit(-1); - } - - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - perror("Cannot create socket"); - exit(1); - } - if (ioctl(fd, cmd, (char*)&ifr) != 0) { - perror("ioctl"); - exit(1); - } - close(fd); - - exit(0); -} - - -int do_multiaddr(int argc, char **argv) -{ - if (argc < 1) - return multiaddr_list(0, NULL); - if (matches(*argv, "add") == 0) - return multiaddr_modify(RTM_NEWADDR, argc-1, argv+1); - if (matches(*argv, "delete") == 0) - return multiaddr_modify(RTM_DELADDR, argc-1, argv+1); - if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 - || matches(*argv, "lst") == 0) - return multiaddr_list(argc-1, argv+1); - if (matches(*argv, "help") == 0) - usage(); - fprintf(stderr, "Command \"%s\" is unknown, try \"ip maddr help\".\n", *argv); - exit(-1); -} diff --git a/ip/ipmonitor.c b/ip/ipmonitor.c deleted file mode 100644 index 50b6327..0000000 --- a/ip/ipmonitor.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * ipmonitor.c "ip monitor". - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <time.h> - -#include "utils.h" -#include "ip_common.h" - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, "Usage: ip monitor [ all | LISTofOBJECTS ]\n"); - exit(-1); -} - - -int accept_msg(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg) -{ - FILE *fp = (FILE*)arg; - - if (timestamp) - print_timestamp(fp); - - if (n->nlmsg_type == RTM_NEWROUTE || n->nlmsg_type == RTM_DELROUTE) { - print_route(who, n, arg); - return 0; - } - if (n->nlmsg_type == RTM_NEWLINK || n->nlmsg_type == RTM_DELLINK) { - ll_remember_index(who, n, NULL); - print_linkinfo(who, n, arg); - return 0; - } - if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) { - print_addrinfo(who, n, arg); - return 0; - } - if (n->nlmsg_type == RTM_NEWNEIGH || n->nlmsg_type == RTM_DELNEIGH) { - print_neigh(who, n, arg); - return 0; - } - if (n->nlmsg_type == RTM_NEWPREFIX) { - print_prefix(who, n, arg); - return 0; - } - if (n->nlmsg_type == 15) { - char *tstr; - time_t secs = ((__u32*)NLMSG_DATA(n))[0]; - long usecs = ((__u32*)NLMSG_DATA(n))[1]; - tstr = asctime(localtime(&secs)); - tstr[strlen(tstr)-1] = 0; - fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs); - return 0; - } - if (n->nlmsg_type == RTM_NEWQDISC || - n->nlmsg_type == RTM_DELQDISC || - n->nlmsg_type == RTM_NEWTCLASS || - n->nlmsg_type == RTM_DELTCLASS || - n->nlmsg_type == RTM_NEWTFILTER || - n->nlmsg_type == RTM_DELTFILTER) - return 0; - if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP && - n->nlmsg_type != NLMSG_DONE) { - fprintf(fp, "Unknown message: %08x %08x %08x\n", - n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); - } - return 0; -} - -int do_ipmonitor(int argc, char **argv) -{ - char *file = NULL; - unsigned groups = ~RTMGRP_TC; - int llink=0; - int laddr=0; - int lroute=0; - int lprefix=0; - - rtnl_close(&rth); - ipaddr_reset_filter(1); - iproute_reset_filter(); - ipneigh_reset_filter(); - - while (argc > 0) { - if (matches(*argv, "file") == 0) { - NEXT_ARG(); - file = *argv; - } else if (matches(*argv, "link") == 0) { - llink=1; - groups = 0; - } else if (matches(*argv, "address") == 0) { - laddr=1; - groups = 0; - } else if (matches(*argv, "route") == 0) { - lroute=1; - groups = 0; - } else if (matches(*argv, "prefix") == 0) { - lprefix=1; - groups = 0; - } else if (strcmp(*argv, "all") == 0) { - groups = ~RTMGRP_TC; - } else if (matches(*argv, "help") == 0) { - usage(); - } else { - fprintf(stderr, "Argument \"%s\" is unknown, try \"ip monitor help\".\n", *argv); - exit(-1); - } - argc--; argv++; - } - - if (llink) - groups |= RTMGRP_LINK; - if (laddr) { - if (!preferred_family || preferred_family == AF_INET) - groups |= RTMGRP_IPV4_IFADDR; - if (!preferred_family || preferred_family == AF_INET6) - groups |= RTMGRP_IPV6_IFADDR; - } - if (lroute) { - if (!preferred_family || preferred_family == AF_INET) - groups |= RTMGRP_IPV4_ROUTE; - if (!preferred_family || preferred_family == AF_INET6) - groups |= RTMGRP_IPV6_ROUTE; - } - if (lprefix) { - if (!preferred_family || preferred_family == AF_INET6) - groups |= RTMGRP_IPV6_PREFIX; - } - - if (file) { - FILE *fp; - fp = fopen(file, "r"); - if (fp == NULL) { - perror("Cannot fopen"); - exit(-1); - } - return rtnl_from_file(fp, accept_msg, stdout); - } - - if (rtnl_open(&rth, groups) < 0) - exit(1); - ll_init_map(&rth); - - if (rtnl_listen(&rth, accept_msg, stdout) < 0) - exit(2); - - return 0; -} diff --git a/ip/ipmroute.c b/ip/ipmroute.c deleted file mode 100644 index 951a54f..0000000 --- a/ip/ipmroute.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * ipmroute.c "ip mroute". - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include <linux/netdevice.h> -#include <linux/if.h> -#include <linux/if_arp.h> -#include <linux/sockios.h> - -#include "utils.h" - -char filter_dev[16]; -int filter_family; - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, "Usage: ip mroute show [ PREFIX ] [ from PREFIX ] [ iif DEVICE ]\n"); -#if 0 - fprintf(stderr, "Usage: ip mroute [ add | del ] DESTINATION from SOURCE [ iif DEVICE ] [ oif DEVICE ]\n"); -#endif - exit(-1); -} - -static char *viftable[32]; - -struct rtfilter -{ - inet_prefix mdst; - inet_prefix msrc; -} filter; - -static void read_viftable(void) -{ - char buf[256]; - FILE *fp = fopen("/proc/net/ip_mr_vif", "r"); - - if (!fp) - return; - - fgets(buf, sizeof(buf), fp); - - while (fgets(buf, sizeof(buf), fp)) { - int vifi; - char dev[256]; - - if (sscanf(buf, "%d%s", &vifi, dev) < 2) - continue; - - if (vifi<0 || vifi>31) - continue; - - viftable[vifi] = strdup(dev); - } - fclose(fp); -} - -static void read_mroute_list(FILE *ofp) -{ - char buf[256]; - FILE *fp = fopen("/proc/net/ip_mr_cache", "r"); - - if (!fp) - return; - - fgets(buf, sizeof(buf), fp); - - while (fgets(buf, sizeof(buf), fp)) { - inet_prefix maddr, msrc; - unsigned pkts, b, w; - int vifi; - char oiflist[256]; - char sbuf[256]; - char mbuf[256]; - char obuf[256]; - - oiflist[0] = 0; - if (sscanf(buf, "%x%x%d%u%u%u%s", maddr.data, msrc.data, &vifi, - &pkts, &b, &w, oiflist) < 6) - continue; - - if (vifi!=-1 && (vifi < 0 || vifi>31)) - continue; - - if (filter_dev[0] && (vifi<0 || strcmp(filter_dev, viftable[vifi]))) - continue; - if (filter.mdst.family && inet_addr_match(&maddr, &filter.mdst, filter.mdst.bitlen)) - continue; - if (filter.msrc.family && inet_addr_match(&msrc, &filter.msrc, filter.msrc.bitlen)) - continue; - - snprintf(obuf, sizeof(obuf), "(%s, %s)", - format_host(AF_INET, 4, &msrc.data[0], sbuf, sizeof(sbuf)), - format_host(AF_INET, 4, &maddr.data[0], mbuf, sizeof(mbuf))); - - fprintf(ofp, "%-32s Iif: ", obuf); - - if (vifi == -1) - fprintf(ofp, "unresolved "); - else - fprintf(ofp, "%-10s ", viftable[vifi]); - - if (oiflist[0]) { - char *next = NULL; - char *p = oiflist; - int ovifi, ottl; - - fprintf(ofp, "Oifs: "); - - while (p) { - next = strchr(p, ' '); - if (next) { - *next = 0; - next++; - } - if (sscanf(p, "%d:%d", &ovifi, &ottl)<2) { - p = next; - continue; - } - p = next; - - fprintf(ofp, "%s", viftable[ovifi]); - if (ottl>1) - fprintf(ofp, "(ttl %d) ", ovifi); - else - fprintf(ofp, " "); - } - } - - if (show_stats && b) { - fprintf(ofp, "%s %u packets, %u bytes", _SL_, pkts, b); - if (w) - fprintf(ofp, ", %u arrived on wrong iif.", w); - } - fprintf(ofp, "\n"); - } - fclose(fp); -} - - -static int mroute_list(int argc, char **argv) -{ - while (argc > 0) { - if (strcmp(*argv, "iif") == 0) { - NEXT_ARG(); - strncpy(filter_dev, *argv, sizeof(filter_dev)-1); - } else if (matches(*argv, "from") == 0) { - NEXT_ARG(); - get_prefix(&filter.msrc, *argv, AF_INET); - } else { - if (strcmp(*argv, "to") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "help") == 0) - usage(); - get_prefix(&filter.mdst, *argv, AF_INET); - } - argv++; argc--; - } - - read_viftable(); - read_mroute_list(stdout); - return 0; -} - -int do_multiroute(int argc, char **argv) -{ - if (argc < 1) - return mroute_list(0, NULL); -#if 0 - if (matches(*argv, "add") == 0) - return mroute_modify(RTM_NEWADDR, argc-1, argv+1); - if (matches(*argv, "delete") == 0) - return mroute_modify(RTM_DELADDR, argc-1, argv+1); - if (matches(*argv, "get") == 0) - return mroute_get(argc-1, argv+1); -#endif - if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 - || matches(*argv, "lst") == 0) - return mroute_list(argc-1, argv+1); - if (matches(*argv, "help") == 0) - usage(); - fprintf(stderr, "Command \"%s\" is unknown, try \"ip mroute help\".\n", *argv); - exit(-1); -} diff --git a/ip/ipneigh.c b/ip/ipneigh.c deleted file mode 100644 index 249ee68..0000000 --- a/ip/ipneigh.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * ipneigh.c "ip neigh". - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - * - * Changes: - * - * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <string.h> -#include <sys/time.h> -#include <net/if.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/ip.h> - -#include "rt_names.h" -#include "utils.h" -#include "ip_common.h" - -#define NUD_VALID (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY) -#define MAX_ROUNDS 10 - -static struct -{ - int family; - int index; - int state; - int unused_only; - inet_prefix pfx; - int flushed; - char *flushb; - int flushp; - int flushe; -} filter; - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, "Usage: ip neigh { add | del | change | replace } { ADDR [ lladdr LLADDR ]\n" - " [ nud { permanent | noarp | stale | reachable } ]\n" - " | proxy ADDR } [ dev DEV ]\n"); - fprintf(stderr, " ip neigh {show|flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]\n"); - exit(-1); -} - -int nud_state_a2n(unsigned *state, char *arg) -{ - if (matches(arg, "permanent") == 0) - *state = NUD_PERMANENT; - else if (matches(arg, "reachable") == 0) - *state = NUD_REACHABLE; - else if (strcmp(arg, "noarp") == 0) - *state = NUD_NOARP; - else if (strcmp(arg, "none") == 0) - *state = NUD_NONE; - else if (strcmp(arg, "stale") == 0) - *state = NUD_STALE; - else if (strcmp(arg, "incomplete") == 0) - *state = NUD_INCOMPLETE; - else if (strcmp(arg, "delay") == 0) - *state = NUD_DELAY; - else if (strcmp(arg, "probe") == 0) - *state = NUD_PROBE; - else if (matches(arg, "failed") == 0) - *state = NUD_FAILED; - else { - if (get_unsigned(state, arg, 0)) - return -1; - if (*state>=0x100 || (*state&((*state)-1))) - return -1; - } - return 0; -} - -static int flush_update(void) -{ - if (rtnl_send(&rth, filter.flushb, filter.flushp) < 0) { - perror("Failed to send flush request\n"); - return -1; - } - filter.flushp = 0; - return 0; -} - - -static int ipneigh_modify(int cmd, int flags, int argc, char **argv) -{ - struct { - struct nlmsghdr n; - struct ndmsg ndm; - char buf[256]; - } req; - char *d = NULL; - int dst_ok = 0; - int lladdr_ok = 0; - char * lla = NULL; - inet_prefix dst; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|flags; - req.n.nlmsg_type = cmd; - req.ndm.ndm_family = preferred_family; - req.ndm.ndm_state = NUD_PERMANENT; - - while (argc > 0) { - if (matches(*argv, "lladdr") == 0) { - NEXT_ARG(); - if (lladdr_ok) - duparg("lladdr", *argv); - lla = *argv; - lladdr_ok = 1; - } else if (strcmp(*argv, "nud") == 0) { - unsigned state; - NEXT_ARG(); - if (nud_state_a2n(&state, *argv)) - invarg("nud state is bad", *argv); - req.ndm.ndm_state = state; - } else if (matches(*argv, "proxy") == 0) { - NEXT_ARG(); - if (matches(*argv, "help") == 0) - usage(); - if (dst_ok) - duparg("address", *argv); - get_addr(&dst, *argv, preferred_family); - dst_ok = 1; - req.ndm.ndm_flags |= NTF_PROXY; - } else if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - d = *argv; - } else { - if (strcmp(*argv, "to") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "help") == 0) { - NEXT_ARG(); - } - if (dst_ok) - duparg2("to", *argv); - get_addr(&dst, *argv, preferred_family); - dst_ok = 1; - } - argc--; argv++; - } - if (d == NULL || !dst_ok || dst.family == AF_UNSPEC) { - fprintf(stderr, "Device and destination are required arguments.\n"); - exit(-1); - } - req.ndm.ndm_family = dst.family; - addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen); - - if (lla && strcmp(lla, "null")) { - char llabuf[20]; - int l; - - l = ll_addr_a2n(llabuf, sizeof(llabuf), lla); - addattr_l(&req.n, sizeof(req), NDA_LLADDR, llabuf, l); - } - - ll_init_map(&rth); - - if ((req.ndm.ndm_ifindex = ll_name_to_index(d)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return -1; - } - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - exit(2); - - return 0; -} - - -int print_neigh(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) -{ - FILE *fp = (FILE*)arg; - struct ndmsg *r = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr * tb[NDA_MAX+1]; - char abuf[256]; - - if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) { - fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n", - n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); - - return 0; - } - len -= NLMSG_LENGTH(sizeof(*r)); - if (len < 0) { - fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); - return -1; - } - - if (filter.flushb && n->nlmsg_type != RTM_NEWNEIGH) - return 0; - - if (filter.family && filter.family != r->ndm_family) - return 0; - if (filter.index && filter.index != r->ndm_ifindex) - return 0; - if (!(filter.state&r->ndm_state) && - (r->ndm_state || !(filter.state&0x100)) && - (r->ndm_family != AF_DECnet)) - return 0; - - parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); - - if (tb[NDA_DST]) { - if (filter.pfx.family) { - inet_prefix dst; - memset(&dst, 0, sizeof(dst)); - dst.family = r->ndm_family; - memcpy(&dst.data, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); - if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) - return 0; - } - } - if (filter.unused_only && tb[NDA_CACHEINFO]) { - struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); - if (ci->ndm_refcnt) - return 0; - } - - if (filter.flushb) { - struct nlmsghdr *fn; - if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { - if (flush_update()) - return -1; - } - fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); - memcpy(fn, n, n->nlmsg_len); - fn->nlmsg_type = RTM_DELNEIGH; - fn->nlmsg_flags = NLM_F_REQUEST; - fn->nlmsg_seq = ++rth.seq; - filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb; - filter.flushed++; - if (show_stats < 2) - return 0; - } - - if (tb[NDA_DST]) { - fprintf(fp, "%s ", - format_host(r->ndm_family, - RTA_PAYLOAD(tb[NDA_DST]), - RTA_DATA(tb[NDA_DST]), - abuf, sizeof(abuf))); - } - if (!filter.index && r->ndm_ifindex) - fprintf(fp, "dev %s ", ll_index_to_name(r->ndm_ifindex)); - if (tb[NDA_LLADDR]) { - SPRINT_BUF(b1); - fprintf(fp, "lladdr %s", ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]), - RTA_PAYLOAD(tb[NDA_LLADDR]), - ll_index_to_type(r->ndm_ifindex), - b1, sizeof(b1))); - } - if (r->ndm_flags & NTF_ROUTER) { - fprintf(fp, " router"); - } - if (tb[NDA_CACHEINFO] && show_stats) { - static int hz; - struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); - if (!hz) - hz = get_hz(); - if (ci->ndm_refcnt) - printf(" ref %d", ci->ndm_refcnt); - fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz, - ci->ndm_confirmed/hz, ci->ndm_updated/hz); - } - -#ifdef NDA_PROBES - if (tb[NDA_PROBES] && show_stats) { - __u32 p = *(__u32 *) RTA_DATA(tb[NDA_PROBES]); - fprintf(fp, " probes %u", p); - } -#endif - - if (r->ndm_state) { - int nud = r->ndm_state; - fprintf(fp, " "); - -#define PRINT_FLAG(f) if (nud & NUD_##f) { \ - nud &= ~NUD_##f; fprintf(fp, #f "%s", nud ? "," : ""); } - PRINT_FLAG(INCOMPLETE); - PRINT_FLAG(REACHABLE); - PRINT_FLAG(STALE); - PRINT_FLAG(DELAY); - PRINT_FLAG(PROBE); - PRINT_FLAG(FAILED); - PRINT_FLAG(NOARP); - PRINT_FLAG(PERMANENT); -#undef PRINT_FLAG - } - fprintf(fp, "\n"); - - fflush(fp); - return 0; -} - -void ipneigh_reset_filter() -{ - memset(&filter, 0, sizeof(filter)); - filter.state = ~0; -} - -int do_show_or_flush(int argc, char **argv, int flush) -{ - char *filter_dev = NULL; - int state_given = 0; - - ipneigh_reset_filter(); - - if (!filter.family) - filter.family = preferred_family; - - if (flush) { - if (argc <= 0) { - fprintf(stderr, "Flush requires arguments.\n"); - return -1; - } - filter.state = ~(NUD_PERMANENT|NUD_NOARP); - } else - filter.state = 0xFF & ~NUD_NOARP; - - while (argc > 0) { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - if (filter_dev) - duparg("dev", *argv); - filter_dev = *argv; - } else if (strcmp(*argv, "unused") == 0) { - filter.unused_only = 1; - } else if (strcmp(*argv, "nud") == 0) { - unsigned state; - NEXT_ARG(); - if (!state_given) { - state_given = 1; - filter.state = 0; - } - if (nud_state_a2n(&state, *argv)) { - if (strcmp(*argv, "all") != 0) - invarg("nud state is bad", *argv); - state = ~0; - if (flush) - state &= ~NUD_NOARP; - } - if (state == 0) - state = 0x100; - filter.state |= state; - } else { - if (strcmp(*argv, "to") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "help") == 0) - usage(); - get_prefix(&filter.pfx, *argv, filter.family); - if (filter.family == AF_UNSPEC) - filter.family = filter.pfx.family; - } - argc--; argv++; - } - - ll_init_map(&rth); - - if (filter_dev) { - if ((filter.index = ll_name_to_index(filter_dev)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", filter_dev); - return -1; - } - } - - if (flush) { - int round = 0; - char flushb[4096-512]; - - filter.flushb = flushb; - filter.flushp = 0; - filter.flushe = sizeof(flushb); - filter.state &= ~NUD_FAILED; - - while (round < MAX_ROUNDS) { - if (rtnl_wilddump_request(&rth, filter.family, RTM_GETNEIGH) < 0) { - perror("Cannot send dump request"); - exit(1); - } - filter.flushed = 0; - if (rtnl_dump_filter(&rth, print_neigh, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Flush terminated\n"); - exit(1); - } - if (filter.flushed == 0) { - if (round == 0) { - fprintf(stderr, "Nothing to flush.\n"); - } else if (show_stats) - printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":""); - fflush(stdout); - return 0; - } - round++; - if (flush_update() < 0) - exit(1); - if (show_stats) { - printf("\n*** Round %d, deleting %d entries ***\n", round, filter.flushed); - fflush(stdout); - } - } - printf("*** Flush not complete bailing out after %d rounds\n", - MAX_ROUNDS); - return 1; - } - - if (rtnl_wilddump_request(&rth, filter.family, RTM_GETNEIGH) < 0) { - perror("Cannot send dump request"); - exit(1); - } - - if (rtnl_dump_filter(&rth, print_neigh, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - exit(1); - } - - return 0; -} - -int do_ipneigh(int argc, char **argv) -{ - if (argc > 0) { - if (matches(*argv, "add") == 0) - return ipneigh_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1); - if (matches(*argv, "change") == 0 || - strcmp(*argv, "chg") == 0) - return ipneigh_modify(RTM_NEWNEIGH, NLM_F_REPLACE, argc-1, argv+1); - if (matches(*argv, "replace") == 0) - return ipneigh_modify(RTM_NEWNEIGH, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1); - if (matches(*argv, "delete") == 0) - return ipneigh_modify(RTM_DELNEIGH, 0, argc-1, argv+1); - if (matches(*argv, "get") == 0) { - fprintf(stderr, "Sorry, \"neigh get\" is not implemented :-(\n"); - return -1; - } - if (matches(*argv, "show") == 0 || - matches(*argv, "lst") == 0 || - matches(*argv, "list") == 0) - return do_show_or_flush(argc-1, argv+1, 0); - if (matches(*argv, "flush") == 0) - return do_show_or_flush(argc-1, argv+1, 1); - if (matches(*argv, "help") == 0) - usage(); - } else - return do_show_or_flush(0, NULL, 0); - - fprintf(stderr, "Command \"%s\" is unknown, try \"ip neigh help\".\n", *argv); - exit(-1); -} diff --git a/ip/ipntable.c b/ip/ipntable.c deleted file mode 100644 index 5655d93..0000000 --- a/ip/ipntable.c +++ /dev/null @@ -1,657 +0,0 @@ -/* - * Copyright (C)2006 USAGI/WIDE Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -/* - * based on ipneigh.c - */ -/* - * Authors: - * Masahide NAKAMURA @USAGI - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/time.h> -#include <time.h> - -#include "utils.h" -#include "ip_common.h" - -static struct -{ - int family; - int index; -#define NONE_DEV (-1) - char name[1024]; -} filter; - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, - "Usage: ip ntable change name NAME [ dev DEV ]\n" - " [ thresh1 VAL ] [ thresh2 VAL ] [ thresh3 VAL ] [ gc_int MSEC ]\n" - " [ PARMS ]\n" - "Usage: ip ntable show [ dev DEV ] [ name NAME ]\n" - - "PARMS := [ base_reachable MSEC ] [ retrans MSEC ] [ gc_stale MSEC ]\n" - " [ delay_probe MSEC ] [ queue LEN ]\n" - " [ app_probs VAL ] [ ucast_probes VAL ] [ mcast_probes VAL ]\n" - " [ anycast_delay MSEC ] [ proxy_delay MSEC ] [ proxy_queue LEN ]\n" - " [ locktime MSEC ]\n" - ); - - exit(-1); -} - -static int ipntable_modify(int cmd, int flags, int argc, char **argv) -{ - struct { - struct nlmsghdr n; - struct ndtmsg ndtm; - char buf[1024]; - } req; - char *namep = NULL; - char *threshsp = NULL; - char *gc_intp = NULL; - char parms_buf[1024]; - struct rtattr *parms_rta = (struct rtattr *)parms_buf; - int parms_change = 0; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndtmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|flags; - req.n.nlmsg_type = cmd; - - req.ndtm.ndtm_family = preferred_family; - req.ndtm.ndtm_pad1 = 0; - req.ndtm.ndtm_pad2 = 0; - - memset(&parms_buf, 0, sizeof(parms_buf)); - - parms_rta->rta_type = NDTA_PARMS; - parms_rta->rta_len = RTA_LENGTH(0); - - while (argc > 0) { - if (strcmp(*argv, "name") == 0) { - int len; - - NEXT_ARG(); - if (namep) - duparg("NAME", *argv); - - namep = *argv; - len = strlen(namep) + 1; - addattr_l(&req.n, sizeof(req), NDTA_NAME, namep, len); - } else if (strcmp(*argv, "thresh1") == 0) { - __u32 thresh1; - - NEXT_ARG(); - threshsp = *argv; - - if (get_u32(&thresh1, *argv, 0)) - invarg("\"thresh1\" value is invalid", *argv); - - addattr32(&req.n, sizeof(req), NDTA_THRESH1, thresh1); - } else if (strcmp(*argv, "thresh2") == 0) { - __u32 thresh2; - - NEXT_ARG(); - threshsp = *argv; - - if (get_u32(&thresh2, *argv, 0)) - invarg("\"thresh2\" value is invalid", *argv); - - addattr32(&req.n, sizeof(req), NDTA_THRESH2, thresh2); - } else if (strcmp(*argv, "thresh3") == 0) { - __u32 thresh3; - - NEXT_ARG(); - threshsp = *argv; - - if (get_u32(&thresh3, *argv, 0)) - invarg("\"thresh3\" value is invalid", *argv); - - addattr32(&req.n, sizeof(req), NDTA_THRESH3, thresh3); - } else if (strcmp(*argv, "gc_int") == 0) { - __u64 gc_int; - - NEXT_ARG(); - gc_intp = *argv; - - if (get_u64(&gc_int, *argv, 0)) - invarg("\"gc_int\" value is invalid", *argv); - - addattr_l(&req.n, sizeof(req), NDTA_GC_INTERVAL, - &gc_int, sizeof(gc_int)); - } else if (strcmp(*argv, "dev") == 0) { - __u32 ifindex; - - NEXT_ARG(); - ifindex = ll_name_to_index(*argv); - if (ifindex == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", *argv); - return -1; - } - - rta_addattr32(parms_rta, sizeof(parms_buf), - NDTPA_IFINDEX, ifindex); - } else if (strcmp(*argv, "base_reachable") == 0) { - __u64 breachable; - - NEXT_ARG(); - - if (get_u64(&breachable, *argv, 0)) - invarg("\"base_reachable\" value is invalid", *argv); - - rta_addattr_l(parms_rta, sizeof(parms_buf), - NDTPA_BASE_REACHABLE_TIME, - &breachable, sizeof(breachable)); - parms_change = 1; - } else if (strcmp(*argv, "retrans") == 0) { - __u64 retrans; - - NEXT_ARG(); - - if (get_u64(&retrans, *argv, 0)) - invarg("\"retrans\" value is invalid", *argv); - - rta_addattr_l(parms_rta, sizeof(parms_buf), - NDTPA_RETRANS_TIME, - &retrans, sizeof(retrans)); - parms_change = 1; - } else if (strcmp(*argv, "gc_stale") == 0) { - __u64 gc_stale; - - NEXT_ARG(); - - if (get_u64(&gc_stale, *argv, 0)) - invarg("\"gc_stale\" value is invalid", *argv); - - rta_addattr_l(parms_rta, sizeof(parms_buf), - NDTPA_GC_STALETIME, - &gc_stale, sizeof(gc_stale)); - parms_change = 1; - } else if (strcmp(*argv, "delay_probe") == 0) { - __u64 delay_probe; - - NEXT_ARG(); - - if (get_u64(&delay_probe, *argv, 0)) - invarg("\"delay_probe\" value is invalid", *argv); - - rta_addattr_l(parms_rta, sizeof(parms_buf), - NDTPA_DELAY_PROBE_TIME, - &delay_probe, sizeof(delay_probe)); - parms_change = 1; - } else if (strcmp(*argv, "queue") == 0) { - __u32 queue; - - NEXT_ARG(); - - if (get_u32(&queue, *argv, 0)) - invarg("\"queue\" value is invalid", *argv); - - if (!parms_rta) - parms_rta = (struct rtattr *)&parms_buf; - rta_addattr32(parms_rta, sizeof(parms_buf), - NDTPA_QUEUE_LEN, queue); - parms_change = 1; - } else if (strcmp(*argv, "app_probes") == 0) { - __u32 aprobe; - - NEXT_ARG(); - - if (get_u32(&aprobe, *argv, 0)) - invarg("\"app_probes\" value is invalid", *argv); - - rta_addattr32(parms_rta, sizeof(parms_buf), - NDTPA_APP_PROBES, aprobe); - parms_change = 1; - } else if (strcmp(*argv, "ucast_probes") == 0) { - __u32 uprobe; - - NEXT_ARG(); - - if (get_u32(&uprobe, *argv, 0)) - invarg("\"ucast_probes\" value is invalid", *argv); - - rta_addattr32(parms_rta, sizeof(parms_buf), - NDTPA_UCAST_PROBES, uprobe); - parms_change = 1; - } else if (strcmp(*argv, "mcast_probes") == 0) { - __u32 mprobe; - - NEXT_ARG(); - - if (get_u32(&mprobe, *argv, 0)) - invarg("\"mcast_probes\" value is invalid", *argv); - - rta_addattr32(parms_rta, sizeof(parms_buf), - NDTPA_MCAST_PROBES, mprobe); - parms_change = 1; - } else if (strcmp(*argv, "anycast_delay") == 0) { - __u64 anycast_delay; - - NEXT_ARG(); - - if (get_u64(&anycast_delay, *argv, 0)) - invarg("\"anycast_delay\" value is invalid", *argv); - - rta_addattr_l(parms_rta, sizeof(parms_buf), - NDTPA_ANYCAST_DELAY, - &anycast_delay, sizeof(anycast_delay)); - parms_change = 1; - } else if (strcmp(*argv, "proxy_delay") == 0) { - __u64 proxy_delay; - - NEXT_ARG(); - - if (get_u64(&proxy_delay, *argv, 0)) - invarg("\"proxy_delay\" value is invalid", *argv); - - rta_addattr_l(parms_rta, sizeof(parms_buf), - NDTPA_PROXY_DELAY, - &proxy_delay, sizeof(proxy_delay)); - parms_change = 1; - } else if (strcmp(*argv, "proxy_queue") == 0) { - __u32 pqueue; - - NEXT_ARG(); - - if (get_u32(&pqueue, *argv, 0)) - invarg("\"proxy_queue\" value is invalid", *argv); - - rta_addattr32(parms_rta, sizeof(parms_buf), - NDTPA_PROXY_QLEN, pqueue); - parms_change = 1; - } else if (strcmp(*argv, "locktime") == 0) { - __u64 locktime; - - NEXT_ARG(); - - if (get_u64(&locktime, *argv, 0)) - invarg("\"locktime\" value is invalid", *argv); - - rta_addattr_l(parms_rta, sizeof(parms_buf), - NDTPA_LOCKTIME, - &locktime, sizeof(locktime)); - parms_change = 1; - } else { - invarg("unknown", *argv); - } - - argc--; argv++; - } - - if (!namep) - missarg("NAME"); - if (!threshsp && !gc_intp && !parms_change) { - fprintf(stderr, "Not enough information: changable attributes required.\n"); - exit(-1); - } - - if (parms_rta->rta_len > RTA_LENGTH(0)) { - addattr_l(&req.n, sizeof(req), NDTA_PARMS, RTA_DATA(parms_rta), - RTA_PAYLOAD(parms_rta)); - } - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - exit(2); - - return 0; -} - -static const char *ntable_strtime_delta(__u32 msec) -{ - static char str[32]; - struct timeval now; - time_t t; - struct tm *tp; - - if (msec == 0) - goto error; - - memset(&now, 0, sizeof(now)); - - if (gettimeofday(&now, NULL) < 0) { - perror("gettimeofday"); - goto error; - } - - t = now.tv_sec - (msec / 1000); - tp = localtime(&t); - if (!tp) - goto error; - - strftime(str, sizeof(str), "%Y-%m-%d %T", tp); - - return str; - error: - strcpy(str, "(error)"); - return str; -} - -int print_ntable(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) -{ - FILE *fp = (FILE*)arg; - struct ndtmsg *ndtm = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr *tb[NDTA_MAX+1]; - struct rtattr *tpb[NDTPA_MAX+1]; - int ret; - - if (n->nlmsg_type != RTM_NEWNEIGHTBL) { - fprintf(stderr, "Not NEIGHTBL: %08x %08x %08x\n", - n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); - return 0; - } - len -= NLMSG_LENGTH(sizeof(*ndtm)); - if (len < 0) { - fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); - return -1; - } - - if (preferred_family && preferred_family != ndtm->ndtm_family) - return 0; - - parse_rtattr(tb, NDTA_MAX, NDTA_RTA(ndtm), - n->nlmsg_len - NLMSG_LENGTH(sizeof(*ndtm))); - - if (tb[NDTA_NAME]) { - char *name = RTA_DATA(tb[NDTA_NAME]); - - if (strlen(filter.name) > 0 && strcmp(filter.name, name)) - return 0; - } - if (tb[NDTA_PARMS]) { - parse_rtattr(tpb, NDTPA_MAX, RTA_DATA(tb[NDTA_PARMS]), - RTA_PAYLOAD(tb[NDTA_PARMS])); - - if (tpb[NDTPA_IFINDEX]) { - __u32 ifindex = *(__u32 *)RTA_DATA(tpb[NDTPA_IFINDEX]); - - if (filter.index && filter.index != ifindex) - return 0; - } else { - if (filter.index && filter.index != NONE_DEV) - return 0; - } - } - - if (ndtm->ndtm_family == AF_INET) - fprintf(fp, "inet "); - else if (ndtm->ndtm_family == AF_INET6) - fprintf(fp, "inet6 "); - else if (ndtm->ndtm_family == AF_DECnet) - fprintf(fp, "dnet "); - else - fprintf(fp, "(%d) ", ndtm->ndtm_family); - - if (tb[NDTA_NAME]) { - char *name = RTA_DATA(tb[NDTA_NAME]); - fprintf(fp, "%s ", name); - } - - fprintf(fp, "%s", _SL_); - - ret = (tb[NDTA_THRESH1] || tb[NDTA_THRESH2] || tb[NDTA_THRESH3] || - tb[NDTA_GC_INTERVAL]); - if (ret) - fprintf(fp, " "); - - if (tb[NDTA_THRESH1]) { - __u32 thresh1 = *(__u32 *)RTA_DATA(tb[NDTA_THRESH1]); - fprintf(fp, "thresh1 %u ", thresh1); - } - if (tb[NDTA_THRESH2]) { - __u32 thresh2 = *(__u32 *)RTA_DATA(tb[NDTA_THRESH2]); - fprintf(fp, "thresh2 %u ", thresh2); - } - if (tb[NDTA_THRESH3]) { - __u32 thresh3 = *(__u32 *)RTA_DATA(tb[NDTA_THRESH3]); - fprintf(fp, "thresh3 %u ", thresh3); - } - if (tb[NDTA_GC_INTERVAL]) { - __u64 gc_int = *(__u64 *)RTA_DATA(tb[NDTA_GC_INTERVAL]); - fprintf(fp, "gc_int %llu ", gc_int); - } - - if (ret) - fprintf(fp, "%s", _SL_); - - if (tb[NDTA_CONFIG] && show_stats) { - struct ndt_config *ndtc = RTA_DATA(tb[NDTA_CONFIG]); - - fprintf(fp, " "); - fprintf(fp, "config "); - - fprintf(fp, "key_len %u ", ndtc->ndtc_key_len); - fprintf(fp, "entry_size %u ", ndtc->ndtc_entry_size); - fprintf(fp, "entries %u ", ndtc->ndtc_entries); - - fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - fprintf(fp, "last_flush %s ", - ntable_strtime_delta(ndtc->ndtc_last_flush)); - fprintf(fp, "last_rand %s ", - ntable_strtime_delta(ndtc->ndtc_last_rand)); - - fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - fprintf(fp, "hash_rnd %u ", ndtc->ndtc_hash_rnd); - fprintf(fp, "hash_mask %08x ", ndtc->ndtc_hash_mask); - - fprintf(fp, "hash_chain_gc %u ", ndtc->ndtc_hash_chain_gc); - fprintf(fp, "proxy_qlen %u ", ndtc->ndtc_proxy_qlen); - - fprintf(fp, "%s", _SL_); - } - - if (tb[NDTA_PARMS]) { - if (tpb[NDTPA_IFINDEX]) { - __u32 ifindex = *(__u32 *)RTA_DATA(tpb[NDTPA_IFINDEX]); - - fprintf(fp, " "); - fprintf(fp, "dev %s ", ll_index_to_name(ifindex)); - fprintf(fp, "%s", _SL_); - } - - fprintf(fp, " "); - - if (tpb[NDTPA_REFCNT]) { - __u32 refcnt = *(__u32 *)RTA_DATA(tpb[NDTPA_REFCNT]); - fprintf(fp, "refcnt %u ", refcnt); - } - if (tpb[NDTPA_REACHABLE_TIME]) { - __u64 reachable = *(__u64 *)RTA_DATA(tpb[NDTPA_REACHABLE_TIME]); - fprintf(fp, "reachable %llu ", reachable); - } - if (tpb[NDTPA_BASE_REACHABLE_TIME]) { - __u64 breachable = *(__u64 *)RTA_DATA(tpb[NDTPA_BASE_REACHABLE_TIME]); - fprintf(fp, "base_reachable %llu ", breachable); - } - if (tpb[NDTPA_RETRANS_TIME]) { - __u64 retrans = *(__u64 *)RTA_DATA(tpb[NDTPA_RETRANS_TIME]); - fprintf(fp, "retrans %llu ", retrans); - } - - fprintf(fp, "%s", _SL_); - - fprintf(fp, " "); - - if (tpb[NDTPA_GC_STALETIME]) { - __u64 gc_stale = *(__u64 *)RTA_DATA(tpb[NDTPA_GC_STALETIME]); - fprintf(fp, "gc_stale %llu ", gc_stale); - } - if (tpb[NDTPA_DELAY_PROBE_TIME]) { - __u64 delay_probe = *(__u64 *)RTA_DATA(tpb[NDTPA_DELAY_PROBE_TIME]); - fprintf(fp, "delay_probe %llu ", delay_probe); - } - if (tpb[NDTPA_QUEUE_LEN]) { - __u32 queue = *(__u32 *)RTA_DATA(tpb[NDTPA_QUEUE_LEN]); - fprintf(fp, "queue %u ", queue); - } - - fprintf(fp, "%s", _SL_); - - fprintf(fp, " "); - - if (tpb[NDTPA_APP_PROBES]) { - __u32 aprobe = *(__u32 *)RTA_DATA(tpb[NDTPA_APP_PROBES]); - fprintf(fp, "app_probes %u ", aprobe); - } - if (tpb[NDTPA_UCAST_PROBES]) { - __u32 uprobe = *(__u32 *)RTA_DATA(tpb[NDTPA_UCAST_PROBES]); - fprintf(fp, "ucast_probes %u ", uprobe); - } - if (tpb[NDTPA_MCAST_PROBES]) { - __u32 mprobe = *(__u32 *)RTA_DATA(tpb[NDTPA_MCAST_PROBES]); - fprintf(fp, "mcast_probes %u ", mprobe); - } - - fprintf(fp, "%s", _SL_); - - fprintf(fp, " "); - - if (tpb[NDTPA_ANYCAST_DELAY]) { - __u64 anycast_delay = *(__u64 *)RTA_DATA(tpb[NDTPA_ANYCAST_DELAY]); - fprintf(fp, "anycast_delay %llu ", anycast_delay); - } - if (tpb[NDTPA_PROXY_DELAY]) { - __u64 proxy_delay = *(__u64 *)RTA_DATA(tpb[NDTPA_PROXY_DELAY]); - fprintf(fp, "proxy_delay %llu ", proxy_delay); - } - if (tpb[NDTPA_PROXY_QLEN]) { - __u32 pqueue = *(__u32 *)RTA_DATA(tpb[NDTPA_PROXY_QLEN]); - fprintf(fp, "proxy_queue %u ", pqueue); - } - if (tpb[NDTPA_LOCKTIME]) { - __u64 locktime = *(__u64 *)RTA_DATA(tpb[NDTPA_LOCKTIME]); - fprintf(fp, "locktime %llu ", locktime); - } - - fprintf(fp, "%s", _SL_); - } - - if (tb[NDTA_STATS] && show_stats) { - struct ndt_stats *ndts = RTA_DATA(tb[NDTA_STATS]); - - fprintf(fp, " "); - fprintf(fp, "stats "); - - fprintf(fp, "allocs %llu ", ndts->ndts_allocs); - fprintf(fp, "destroys %llu ", ndts->ndts_destroys); - fprintf(fp, "hash_grows %llu ", ndts->ndts_hash_grows); - - fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - fprintf(fp, "res_failed %llu ", ndts->ndts_res_failed); - fprintf(fp, "lookups %llu ", ndts->ndts_lookups); - fprintf(fp, "hits %llu ", ndts->ndts_hits); - - fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - fprintf(fp, "rcv_probes_mcast %llu ", ndts->ndts_rcv_probes_mcast); - fprintf(fp, "rcv_probes_ucast %llu ", ndts->ndts_rcv_probes_ucast); - - fprintf(fp, "%s", _SL_); - fprintf(fp, " "); - - fprintf(fp, "periodic_gc_runs %llu ", ndts->ndts_periodic_gc_runs); - fprintf(fp, "forced_gc_runs %llu ", ndts->ndts_forced_gc_runs); - - fprintf(fp, "%s", _SL_); - } - - fprintf(fp, "\n"); - - fflush(fp); - return 0; -} - -void ipntable_reset_filter(void) -{ - memset(&filter, 0, sizeof(filter)); -} - -static int ipntable_show(int argc, char **argv) -{ - ipntable_reset_filter(); - - filter.family = preferred_family; - - while (argc > 0) { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - - if (strcmp("none", *argv) == 0) - filter.index = NONE_DEV; - else if ((filter.index = ll_name_to_index(*argv)) == 0) - invarg("\"DEV\" is invalid", *argv); - } else if (strcmp(*argv, "name") == 0) { - NEXT_ARG(); - - strncpy(filter.name, *argv, sizeof(filter.name)); - } else - invarg("unknown", *argv); - - argc--; argv++; - } - - if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETNEIGHTBL) < 0) { - perror("Cannot send dump request"); - exit(1); - } - - if (rtnl_dump_filter(&rth, print_ntable, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - exit(1); - } - - return 0; -} - -int do_ipntable(int argc, char **argv) -{ - ll_init_map(&rth); - - if (argc > 0) { - if (matches(*argv, "change") == 0 || - matches(*argv, "chg") == 0) - return ipntable_modify(RTM_SETNEIGHTBL, - NLM_F_REPLACE, - argc-1, argv+1); - if (matches(*argv, "show") == 0 || - matches(*argv, "lst") == 0 || - matches(*argv, "list") == 0) - return ipntable_show(argc-1, argv+1); - if (matches(*argv, "help") == 0) - usage(); - } else - return ipntable_show(0, NULL); - - fprintf(stderr, "Command \"%s\" is unknown, try \"ip ntable help\".\n", *argv); - exit(-1); -} diff --git a/ip/ipprefix.c b/ip/ipprefix.c deleted file mode 100644 index 61d12f9..0000000 --- a/ip/ipprefix.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C)2005 USAGI/WIDE Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -/* - * based on ip.c, iproute.c - */ -/* - * Authors: - * Masahide NAKAMURA @USAGI - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netinet/icmp6.h> -#include "utils.h" - -/* prefix flags; see kernel's net/ipv6/addrconf.c and include/net/if_inet6.h */ -#define IF_PREFIX_ONLINK 0x01 -#define IF_PREFIX_AUTOCONF 0x02 - -int print_prefix(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) -{ - FILE *fp = (FILE*)arg; - struct prefixmsg *prefix = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr * tb[RTA_MAX+1]; - int family = preferred_family; - - if (n->nlmsg_type != RTM_NEWPREFIX) { - fprintf(stderr, "Not a prefix: %08x %08x %08x\n", - n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); - return 0; - } - - len -= NLMSG_LENGTH(sizeof(*prefix)); - if (len < 0) { - fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); - return -1; - } - - if (family == AF_UNSPEC) - family = AF_INET6; - if (family != AF_INET6) - return 0; - - if (prefix->prefix_family != AF_INET6) { - fprintf(stderr, "wrong family %d\n", prefix->prefix_family); - return 0; - } - if (prefix->prefix_type != ND_OPT_PREFIX_INFORMATION) { - fprintf(stderr, "wrong ND type %d\n", prefix->prefix_type); - return 0; - } - - parse_rtattr(tb, RTA_MAX, RTM_RTA(prefix), len); - - fprintf(fp, "prefix "); - - if (tb[PREFIX_ADDRESS]) { - struct in6_addr *pfx; - char abuf[256]; - - pfx = (struct in6_addr *)RTA_DATA(tb[PREFIX_ADDRESS]); - - memset(abuf, '\0', sizeof(abuf)); - fprintf(fp, "%s", rt_addr_n2a(family, sizeof(*pfx), pfx, - abuf, sizeof(abuf))); - } - fprintf(fp, "/%u ", prefix->prefix_len); - - fprintf(fp, "dev %s ", ll_index_to_name(prefix->prefix_ifindex)); - - if (prefix->prefix_flags & IF_PREFIX_ONLINK) - fprintf(fp, "onlink "); - if (prefix->prefix_flags & IF_PREFIX_AUTOCONF) - fprintf(fp, "autoconf "); - - if (tb[PREFIX_CACHEINFO]) { - struct prefix_cacheinfo *pc; - pc = (struct prefix_cacheinfo *)tb[PREFIX_CACHEINFO]; - - fprintf(fp, "valid %u ", pc->valid_time); - fprintf(fp, "preferred %u ", pc->preferred_time); - } - - fprintf(fp, "\n"); - fflush(fp); - - return 0; -} - diff --git a/ip/iproute.c b/ip/iproute.c deleted file mode 100644 index a43c09e..0000000 --- a/ip/iproute.c +++ /dev/null @@ -1,1431 +0,0 @@ -/* - * iproute.c "ip route". - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - * - * Changes: - * - * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses - * Kunihiro Ishiguro <kunihiro@zebra.org> 001102: rtnh_ifindex was not initialized - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <string.h> -#include <time.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <arpa/inet.h> -#include <linux/in_route.h> -#include <linux/ip_mp_alg.h> - -#include "rt_names.h" -#include "utils.h" -#include "ip_common.h" - -#ifndef RTAX_RTTVAR -#define RTAX_RTTVAR RTAX_HOPS -#endif - - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, "Usage: ip route { list | flush } SELECTOR\n"); - fprintf(stderr, " ip route get ADDRESS [ from ADDRESS iif STRING ]\n"); - fprintf(stderr, " [ oif STRING ] [ tos TOS ]\n"); - fprintf(stderr, " ip route { add | del | change | append | replace | monitor } ROUTE\n"); - fprintf(stderr, "SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]\n"); - fprintf(stderr, " [ table TABLE_ID ] [ proto RTPROTO ]\n"); - fprintf(stderr, " [ type TYPE ] [ scope SCOPE ]\n"); - fprintf(stderr, "ROUTE := NODE_SPEC [ INFO_SPEC ]\n"); - fprintf(stderr, "NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ]\n"); - fprintf(stderr, " [ table TABLE_ID ] [ proto RTPROTO ]\n"); - fprintf(stderr, " [ scope SCOPE ] [ metric METRIC ]\n"); - fprintf(stderr, " [ mpath MP_ALGO ]\n"); - fprintf(stderr, "INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...\n"); - fprintf(stderr, "NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS\n"); - fprintf(stderr, "OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ]\n"); - fprintf(stderr, " [ rtt NUMBER ] [ rttvar NUMBER ]\n"); - fprintf(stderr, " [ window NUMBER] [ cwnd NUMBER ] [ ssthresh NUMBER ]\n"); - fprintf(stderr, " [ realms REALM ]\n"); - fprintf(stderr, "TYPE := [ unicast | local | broadcast | multicast | throw |\n"); - fprintf(stderr, " unreachable | prohibit | blackhole | nat ]\n"); - fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n"); - fprintf(stderr, "SCOPE := [ host | link | global | NUMBER ]\n"); - fprintf(stderr, "FLAGS := [ equalize ]\n"); - fprintf(stderr, "MP_ALGO := { rr | drr | random | wrandom }\n"); - fprintf(stderr, "NHFLAGS := [ onlink | pervasive ]\n"); - fprintf(stderr, "RTPROTO := [ kernel | boot | static | NUMBER ]\n"); - exit(-1); -} - - -static struct -{ - int tb; - int flushed; - char *flushb; - int flushp; - int flushe; - int protocol, protocolmask; - int scope, scopemask; - int type, typemask; - int tos, tosmask; - int iif, iifmask; - int oif, oifmask; - int realm, realmmask; - inet_prefix rprefsrc; - inet_prefix rvia; - inet_prefix rdst; - inet_prefix mdst; - inet_prefix rsrc; - inet_prefix msrc; -} filter; - -static char *mp_alg_names[IP_MP_ALG_MAX+1] = { - [IP_MP_ALG_NONE] = "none", - [IP_MP_ALG_RR] = "rr", - [IP_MP_ALG_DRR] = "drr", - [IP_MP_ALG_RANDOM] = "random", - [IP_MP_ALG_WRANDOM] = "wrandom" -}; - -static int flush_update(void) -{ - if (rtnl_send(&rth, filter.flushb, filter.flushp) < 0) { - perror("Failed to send flush request\n"); - return -1; - } - filter.flushp = 0; - return 0; -} - -int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) -{ - FILE *fp = (FILE*)arg; - struct rtmsg *r = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr * tb[RTA_MAX+1]; - char abuf[256]; - inet_prefix dst; - inet_prefix src; - inet_prefix prefsrc; - inet_prefix via; - int host_len = -1; - SPRINT_BUF(b1); - - - if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) { - fprintf(stderr, "Not a route: %08x %08x %08x\n", - n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); - return 0; - } - if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE) - return 0; - len -= NLMSG_LENGTH(sizeof(*r)); - if (len < 0) { - fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); - return -1; - } - - if (r->rtm_family == AF_INET6) - host_len = 128; - else if (r->rtm_family == AF_INET) - host_len = 32; - else if (r->rtm_family == AF_DECnet) - host_len = 16; - else if (r->rtm_family == AF_IPX) - host_len = 80; - - if (r->rtm_family == AF_INET6) { - if (filter.tb) { - if (filter.tb < 0) { - if (!(r->rtm_flags&RTM_F_CLONED)) - return 0; - } else { - if (r->rtm_flags&RTM_F_CLONED) - return 0; - if (filter.tb == RT_TABLE_LOCAL) { - if (r->rtm_type != RTN_LOCAL) - return 0; - } else if (filter.tb == RT_TABLE_MAIN) { - if (r->rtm_type == RTN_LOCAL) - return 0; - } else { - return 0; - } - } - } - } else { - if (filter.tb > 0 && filter.tb != r->rtm_table) - return 0; - } - if ((filter.protocol^r->rtm_protocol)&filter.protocolmask) - return 0; - if ((filter.scope^r->rtm_scope)&filter.scopemask) - return 0; - if ((filter.type^r->rtm_type)&filter.typemask) - return 0; - if ((filter.tos^r->rtm_tos)&filter.tosmask) - return 0; - if (filter.rdst.family && - (r->rtm_family != filter.rdst.family || filter.rdst.bitlen > r->rtm_dst_len)) - return 0; - if (filter.mdst.family && - (r->rtm_family != filter.mdst.family || - (filter.mdst.bitlen >= 0 && filter.mdst.bitlen < r->rtm_dst_len))) - return 0; - if (filter.rsrc.family && - (r->rtm_family != filter.rsrc.family || filter.rsrc.bitlen > r->rtm_src_len)) - return 0; - if (filter.msrc.family && - (r->rtm_family != filter.msrc.family || - (filter.msrc.bitlen >= 0 && filter.msrc.bitlen < r->rtm_src_len))) - return 0; - if (filter.rvia.family && r->rtm_family != filter.rvia.family) - return 0; - if (filter.rprefsrc.family && r->rtm_family != filter.rprefsrc.family) - return 0; - - parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); - - memset(&dst, 0, sizeof(dst)); - dst.family = r->rtm_family; - if (tb[RTA_DST]) - memcpy(&dst.data, RTA_DATA(tb[RTA_DST]), (r->rtm_dst_len+7)/8); - if (filter.rsrc.family || filter.msrc.family) { - memset(&src, 0, sizeof(src)); - src.family = r->rtm_family; - if (tb[RTA_SRC]) - memcpy(&src.data, RTA_DATA(tb[RTA_SRC]), (r->rtm_src_len+7)/8); - } - if (filter.rvia.bitlen>0) { - memset(&via, 0, sizeof(via)); - via.family = r->rtm_family; - if (tb[RTA_GATEWAY]) - memcpy(&via.data, RTA_DATA(tb[RTA_GATEWAY]), host_len/8); - } - if (filter.rprefsrc.bitlen>0) { - memset(&prefsrc, 0, sizeof(prefsrc)); - prefsrc.family = r->rtm_family; - if (tb[RTA_PREFSRC]) - memcpy(&prefsrc.data, RTA_DATA(tb[RTA_PREFSRC]), host_len/8); - } - - if (filter.rdst.family && inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen)) - return 0; - if (filter.mdst.family && filter.mdst.bitlen >= 0 && - inet_addr_match(&dst, &filter.mdst, r->rtm_dst_len)) - return 0; - - if (filter.rsrc.family && inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen)) - return 0; - if (filter.msrc.family && filter.msrc.bitlen >= 0 && - inet_addr_match(&src, &filter.msrc, r->rtm_src_len)) - return 0; - - if (filter.rvia.family && inet_addr_match(&via, &filter.rvia, filter.rvia.bitlen)) - return 0; - if (filter.rprefsrc.family && inet_addr_match(&prefsrc, &filter.rprefsrc, filter.rprefsrc.bitlen)) - return 0; - if (filter.realmmask) { - __u32 realms = 0; - if (tb[RTA_FLOW]) - realms = *(__u32*)RTA_DATA(tb[RTA_FLOW]); - if ((realms^filter.realm)&filter.realmmask) - return 0; - } - if (filter.iifmask) { - int iif = 0; - if (tb[RTA_IIF]) - iif = *(int*)RTA_DATA(tb[RTA_IIF]); - if ((iif^filter.iif)&filter.iifmask) - return 0; - } - if (filter.oifmask) { - int oif = 0; - if (tb[RTA_OIF]) - oif = *(int*)RTA_DATA(tb[RTA_OIF]); - if ((oif^filter.oif)&filter.oifmask) - return 0; - } - if (filter.flushb && - r->rtm_family == AF_INET6 && - r->rtm_dst_len == 0 && - r->rtm_type == RTN_UNREACHABLE && - tb[RTA_PRIORITY] && - *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1) - return 0; - - if (filter.flushb) { - struct nlmsghdr *fn; - if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { - if (flush_update()) - return -1; - } - fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); - memcpy(fn, n, n->nlmsg_len); - fn->nlmsg_type = RTM_DELROUTE; - fn->nlmsg_flags = NLM_F_REQUEST; - fn->nlmsg_seq = ++rth.seq; - filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb; - filter.flushed++; - if (show_stats < 2) - return 0; - } - - if (n->nlmsg_type == RTM_DELROUTE) - fprintf(fp, "Deleted "); - if (r->rtm_type != RTN_UNICAST && !filter.type) - fprintf(fp, "%s ", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1))); - - if (tb[RTA_DST]) { - if (r->rtm_dst_len != host_len) { - fprintf(fp, "%s/%u ", rt_addr_n2a(r->rtm_family, - RTA_PAYLOAD(tb[RTA_DST]), - RTA_DATA(tb[RTA_DST]), - abuf, sizeof(abuf)), - r->rtm_dst_len - ); - } else { - fprintf(fp, "%s ", format_host(r->rtm_family, - RTA_PAYLOAD(tb[RTA_DST]), - RTA_DATA(tb[RTA_DST]), - abuf, sizeof(abuf)) - ); - } - } else if (r->rtm_dst_len) { - fprintf(fp, "0/%d ", r->rtm_dst_len); - } else { - fprintf(fp, "default "); - } - if (tb[RTA_SRC]) { - if (r->rtm_src_len != host_len) { - fprintf(fp, "from %s/%u ", rt_addr_n2a(r->rtm_family, - RTA_PAYLOAD(tb[RTA_SRC]), - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)), - r->rtm_src_len - ); - } else { - fprintf(fp, "from %s ", format_host(r->rtm_family, - RTA_PAYLOAD(tb[RTA_SRC]), - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)) - ); - } - } else if (r->rtm_src_len) { - fprintf(fp, "from 0/%u ", r->rtm_src_len); - } - if (r->rtm_tos && filter.tosmask != -1) { - SPRINT_BUF(b1); - fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1))); - } - - if (tb[RTA_MP_ALGO]) { - __u32 mp_alg = *(__u32*) RTA_DATA(tb[RTA_MP_ALGO]); - if (mp_alg > IP_MP_ALG_NONE) { - fprintf(fp, "mpath %s ", - mp_alg < IP_MP_ALG_MAX ? mp_alg_names[mp_alg] : "unknown"); - } - } - - if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) { - fprintf(fp, "via %s ", - format_host(r->rtm_family, - RTA_PAYLOAD(tb[RTA_GATEWAY]), - RTA_DATA(tb[RTA_GATEWAY]), - abuf, sizeof(abuf))); - } - if (tb[RTA_OIF] && filter.oifmask != -1) - fprintf(fp, "dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF]))); - - if (!(r->rtm_flags&RTM_F_CLONED)) { - if (r->rtm_table != RT_TABLE_MAIN && !filter.tb) - fprintf(fp, " table %s ", rtnl_rttable_n2a(r->rtm_table, b1, sizeof(b1))); - if (r->rtm_protocol != RTPROT_BOOT && filter.protocolmask != -1) - fprintf(fp, " proto %s ", rtnl_rtprot_n2a(r->rtm_protocol, b1, sizeof(b1))); - if (r->rtm_scope != RT_SCOPE_UNIVERSE && filter.scopemask != -1) - fprintf(fp, " scope %s ", rtnl_rtscope_n2a(r->rtm_scope, b1, sizeof(b1))); - } - if (tb[RTA_PREFSRC] && filter.rprefsrc.bitlen != host_len) { - /* Do not use format_host(). It is our local addr - and symbolic name will not be useful. - */ - fprintf(fp, " src %s ", - rt_addr_n2a(r->rtm_family, - RTA_PAYLOAD(tb[RTA_PREFSRC]), - RTA_DATA(tb[RTA_PREFSRC]), - abuf, sizeof(abuf))); - } - if (tb[RTA_PRIORITY]) - fprintf(fp, " metric %d ", *(__u32*)RTA_DATA(tb[RTA_PRIORITY])); - if (r->rtm_flags & RTNH_F_DEAD) - fprintf(fp, "dead "); - if (r->rtm_flags & RTNH_F_ONLINK) - fprintf(fp, "onlink "); - if (r->rtm_flags & RTNH_F_PERVASIVE) - fprintf(fp, "pervasive "); - if (r->rtm_flags & RTM_F_EQUALIZE) - fprintf(fp, "equalize "); - if (r->rtm_flags & RTM_F_NOTIFY) - fprintf(fp, "notify "); - - if (tb[RTA_FLOW] && filter.realmmask != ~0U) { - __u32 to = *(__u32*)RTA_DATA(tb[RTA_FLOW]); - __u32 from = to>>16; - to &= 0xFFFF; - fprintf(fp, "realm%s ", from ? "s" : ""); - if (from) { - fprintf(fp, "%s/", - rtnl_rtrealm_n2a(from, b1, sizeof(b1))); - } - fprintf(fp, "%s ", - rtnl_rtrealm_n2a(to, b1, sizeof(b1))); - } - if ((r->rtm_flags&RTM_F_CLONED) && r->rtm_family == AF_INET) { - __u32 flags = r->rtm_flags&~0xFFFF; - int first = 1; - - fprintf(fp, "%s cache ", _SL_); - -#define PRTFL(fl,flname) if (flags&RTCF_##fl) { \ - flags &= ~RTCF_##fl; \ - fprintf(fp, "%s" flname "%s", first ? "<" : "", flags ? "," : "> "); \ - first = 0; } - PRTFL(LOCAL, "local"); - PRTFL(REJECT, "reject"); - PRTFL(MULTICAST, "mc"); - PRTFL(BROADCAST, "brd"); - PRTFL(DNAT, "dst-nat"); - PRTFL(SNAT, "src-nat"); - PRTFL(MASQ, "masq"); - PRTFL(DIRECTDST, "dst-direct"); - PRTFL(DIRECTSRC, "src-direct"); - PRTFL(REDIRECTED, "redirected"); - PRTFL(DOREDIRECT, "redirect"); - PRTFL(FAST, "fastroute"); - PRTFL(NOTIFY, "notify"); - PRTFL(TPROXY, "proxy"); -#ifdef RTCF_EQUALIZE - PRTFL(EQUALIZE, "equalize"); -#endif - if (flags) - fprintf(fp, "%s%x> ", first ? "<" : "", flags); - if (tb[RTA_CACHEINFO]) { - struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]); - static int hz; - if (!hz) - hz = get_user_hz(); - if (ci->rta_expires != 0) - fprintf(fp, " expires %dsec", ci->rta_expires/hz); - if (ci->rta_error != 0) - fprintf(fp, " error %d", ci->rta_error); - if (show_stats) { - if (ci->rta_clntref) - fprintf(fp, " users %d", ci->rta_clntref); - if (ci->rta_used != 0) - fprintf(fp, " used %d", ci->rta_used); - if (ci->rta_lastuse != 0) - fprintf(fp, " age %dsec", ci->rta_lastuse/hz); - } -#ifdef RTNETLINK_HAVE_PEERINFO - if (ci->rta_id) - fprintf(fp, " ipid 0x%04x", ci->rta_id); - if (ci->rta_ts || ci->rta_tsage) - fprintf(fp, " ts 0x%x tsage %dsec", ci->rta_ts, ci->rta_tsage); -#endif - } - } else if (r->rtm_family == AF_INET6) { - struct rta_cacheinfo *ci = NULL; - if (tb[RTA_CACHEINFO]) - ci = RTA_DATA(tb[RTA_CACHEINFO]); - if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) { - static int hz; - if (!hz) - hz = get_user_hz(); - if (r->rtm_flags & RTM_F_CLONED) - fprintf(fp, "%s cache ", _SL_); - if (ci->rta_expires) - fprintf(fp, " expires %dsec", ci->rta_expires/hz); - if (ci->rta_error != 0) - fprintf(fp, " error %d", ci->rta_error); - if (show_stats) { - if (ci->rta_clntref) - fprintf(fp, " users %d", ci->rta_clntref); - if (ci->rta_used != 0) - fprintf(fp, " used %d", ci->rta_used); - if (ci->rta_lastuse != 0) - fprintf(fp, " age %dsec", ci->rta_lastuse/hz); - } - } else if (ci) { - if (ci->rta_error != 0) - fprintf(fp, " error %d", ci->rta_error); - } - } - if (tb[RTA_METRICS]) { - int i; - unsigned mxlock = 0; - struct rtattr *mxrta[RTAX_MAX+1]; - - parse_rtattr(mxrta, RTAX_MAX, RTA_DATA(tb[RTA_METRICS]), - RTA_PAYLOAD(tb[RTA_METRICS])); - if (mxrta[RTAX_LOCK]) - mxlock = *(unsigned*)RTA_DATA(mxrta[RTAX_LOCK]); - - for (i=2; i<=RTAX_MAX; i++) { - static char *mx_names[] = - { - "mtu", - "window", - "rtt", - "rttvar", - "ssthresh", - "cwnd", - "advmss", - "reordering", - }; - static int hz; - if (mxrta[i] == NULL) - continue; - if (!hz) - hz = get_hz(); - if (i-2 < sizeof(mx_names)/sizeof(char*)) - fprintf(fp, " %s", mx_names[i-2]); - else - fprintf(fp, " metric %d", i); - if (mxlock & (1<<i)) - fprintf(fp, " lock"); - - if (i != RTAX_RTT && i != RTAX_RTTVAR) - fprintf(fp, " %u", *(unsigned*)RTA_DATA(mxrta[i])); - else { - unsigned val = *(unsigned*)RTA_DATA(mxrta[i]); - - val *= 1000; - if (i == RTAX_RTT) - val /= 8; - else - val /= 4; - if (val >= hz) - fprintf(fp, " %ums", val/hz); - else - fprintf(fp, " %.2fms", (float)val/hz); - } - } - } - if (tb[RTA_IIF] && filter.iifmask != -1) { - fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); - } - if (tb[RTA_MULTIPATH]) { - struct rtnexthop *nh = RTA_DATA(tb[RTA_MULTIPATH]); - int first = 0; - - len = RTA_PAYLOAD(tb[RTA_MULTIPATH]); - - for (;;) { - if (len < sizeof(*nh)) - break; - if (nh->rtnh_len > len) - break; - if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) { - if (first) - fprintf(fp, " Oifs:"); - else - fprintf(fp, " "); - } else - fprintf(fp, "%s\tnexthop", _SL_); - if (nh->rtnh_len > sizeof(*nh)) { - parse_rtattr(tb, RTA_MAX, RTNH_DATA(nh), nh->rtnh_len - sizeof(*nh)); - if (tb[RTA_GATEWAY]) { - fprintf(fp, " via %s ", - format_host(r->rtm_family, - RTA_PAYLOAD(tb[RTA_GATEWAY]), - RTA_DATA(tb[RTA_GATEWAY]), - abuf, sizeof(abuf))); - } - } - if (r->rtm_flags&RTM_F_CLONED && r->rtm_type == RTN_MULTICAST) { - fprintf(fp, " %s", ll_index_to_name(nh->rtnh_ifindex)); - if (nh->rtnh_hops != 1) - fprintf(fp, "(ttl>%d)", nh->rtnh_hops); - } else { - fprintf(fp, " dev %s", ll_index_to_name(nh->rtnh_ifindex)); - fprintf(fp, " weight %d", nh->rtnh_hops+1); - } - if (nh->rtnh_flags & RTNH_F_DEAD) - fprintf(fp, " dead"); - if (nh->rtnh_flags & RTNH_F_ONLINK) - fprintf(fp, " onlink"); - if (nh->rtnh_flags & RTNH_F_PERVASIVE) - fprintf(fp, " pervasive"); - len -= NLMSG_ALIGN(nh->rtnh_len); - nh = RTNH_NEXT(nh); - } - } - fprintf(fp, "\n"); - fflush(fp); - return 0; -} - - -int parse_one_nh(struct rtattr *rta, struct rtnexthop *rtnh, int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - - while (++argv, --argc > 0) { - if (strcmp(*argv, "via") == 0) { - NEXT_ARG(); - rta_addattr32(rta, 4096, RTA_GATEWAY, get_addr32(*argv)); - rtnh->rtnh_len += sizeof(struct rtattr) + 4; - } else if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - if ((rtnh->rtnh_ifindex = ll_name_to_index(*argv)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", *argv); - exit(1); - } - } else if (strcmp(*argv, "weight") == 0) { - unsigned w; - NEXT_ARG(); - if (get_unsigned(&w, *argv, 0) || w == 0 || w > 256) - invarg("\"weight\" is invalid\n", *argv); - rtnh->rtnh_hops = w - 1; - } else if (strcmp(*argv, "onlink") == 0) { - rtnh->rtnh_flags |= RTNH_F_ONLINK; - } else - break; - } - *argcp = argc; - *argvp = argv; - return 0; -} - -int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, int argc, char **argv) -{ - char buf[1024]; - struct rtattr *rta = (void*)buf; - struct rtnexthop *rtnh; - - rta->rta_type = RTA_MULTIPATH; - rta->rta_len = RTA_LENGTH(0); - rtnh = RTA_DATA(rta); - - while (argc > 0) { - if (strcmp(*argv, "nexthop") != 0) { - fprintf(stderr, "Error: \"nexthop\" or end of line is expected instead of \"%s\"\n", *argv); - exit(-1); - } - if (argc <= 1) { - fprintf(stderr, "Error: unexpected end of line after \"nexthop\"\n"); - exit(-1); - } - memset(rtnh, 0, sizeof(*rtnh)); - rtnh->rtnh_len = sizeof(*rtnh); - rta->rta_len += rtnh->rtnh_len; - parse_one_nh(rta, rtnh, &argc, &argv); - rtnh = RTNH_NEXT(rtnh); - } - - if (rta->rta_len > RTA_LENGTH(0)) - addattr_l(n, 1024, RTA_MULTIPATH, RTA_DATA(rta), RTA_PAYLOAD(rta)); - return 0; -} - - -int iproute_modify(int cmd, unsigned flags, int argc, char **argv) -{ - struct { - struct nlmsghdr n; - struct rtmsg r; - char buf[1024]; - } req; - char mxbuf[256]; - struct rtattr * mxrta = (void*)mxbuf; - unsigned mxlock = 0; - char *d = NULL; - int gw_ok = 0; - int dst_ok = 0; - int nhs_ok = 0; - int scope_ok = 0; - int table_ok = 0; - int proto_ok = 0; - int type_ok = 0; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|flags; - req.n.nlmsg_type = cmd; - req.r.rtm_family = preferred_family; - req.r.rtm_table = RT_TABLE_MAIN; - req.r.rtm_scope = RT_SCOPE_NOWHERE; - - if (cmd != RTM_DELROUTE) { - req.r.rtm_protocol = RTPROT_BOOT; - req.r.rtm_scope = RT_SCOPE_UNIVERSE; - req.r.rtm_type = RTN_UNICAST; - } - - mxrta->rta_type = RTA_METRICS; - mxrta->rta_len = RTA_LENGTH(0); - - while (argc > 0) { - if (strcmp(*argv, "src") == 0) { - inet_prefix addr; - NEXT_ARG(); - get_addr(&addr, *argv, req.r.rtm_family); - if (req.r.rtm_family == AF_UNSPEC) - req.r.rtm_family = addr.family; - addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &addr.data, addr.bytelen); - } else if (strcmp(*argv, "via") == 0) { - inet_prefix addr; - gw_ok = 1; - NEXT_ARG(); - get_addr(&addr, *argv, req.r.rtm_family); - if (req.r.rtm_family == AF_UNSPEC) - req.r.rtm_family = addr.family; - addattr_l(&req.n, sizeof(req), RTA_GATEWAY, &addr.data, addr.bytelen); - } else if (strcmp(*argv, "from") == 0) { - inet_prefix addr; - NEXT_ARG(); - get_prefix(&addr, *argv, req.r.rtm_family); - if (req.r.rtm_family == AF_UNSPEC) - req.r.rtm_family = addr.family; - if (addr.bytelen) - addattr_l(&req.n, sizeof(req), RTA_SRC, &addr.data, addr.bytelen); - req.r.rtm_src_len = addr.bitlen; - } else if (strcmp(*argv, "tos") == 0 || - matches(*argv, "dsfield") == 0) { - __u32 tos; - NEXT_ARG(); - if (rtnl_dsfield_a2n(&tos, *argv)) - invarg("\"tos\" value is invalid\n", *argv); - req.r.rtm_tos = tos; - } else if (matches(*argv, "metric") == 0 || - matches(*argv, "priority") == 0 || - matches(*argv, "preference") == 0) { - __u32 metric; - NEXT_ARG(); - if (get_u32(&metric, *argv, 0)) - invarg("\"metric\" value is invalid\n", *argv); - addattr32(&req.n, sizeof(req), RTA_PRIORITY, metric); - } else if (strcmp(*argv, "scope") == 0) { - __u32 scope = 0; - NEXT_ARG(); - if (rtnl_rtscope_a2n(&scope, *argv)) - invarg("invalid \"scope\" value\n", *argv); - req.r.rtm_scope = scope; - scope_ok = 1; - } else if (strcmp(*argv, "mtu") == 0) { - unsigned mtu; - NEXT_ARG(); - if (strcmp(*argv, "lock") == 0) { - mxlock |= (1<<RTAX_MTU); - NEXT_ARG(); - } - if (get_unsigned(&mtu, *argv, 0)) - invarg("\"mtu\" value is invalid\n", *argv); - rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); -#ifdef RTAX_ADVMSS - } else if (strcmp(*argv, "advmss") == 0) { - unsigned mss; - NEXT_ARG(); - if (strcmp(*argv, "lock") == 0) { - mxlock |= (1<<RTAX_ADVMSS); - NEXT_ARG(); - } - if (get_unsigned(&mss, *argv, 0)) - invarg("\"mss\" value is invalid\n", *argv); - rta_addattr32(mxrta, sizeof(mxbuf), RTAX_ADVMSS, mss); -#endif -#ifdef RTAX_REORDERING - } else if (matches(*argv, "reordering") == 0) { - unsigned reord; - NEXT_ARG(); - if (strcmp(*argv, "lock") == 0) { - mxlock |= (1<<RTAX_REORDERING); - NEXT_ARG(); - } - if (get_unsigned(&reord, *argv, 0)) - invarg("\"reordering\" value is invalid\n", *argv); - rta_addattr32(mxrta, sizeof(mxbuf), RTAX_REORDERING, reord); -#endif - } else if (strcmp(*argv, "rtt") == 0) { - unsigned rtt; - NEXT_ARG(); - if (strcmp(*argv, "lock") == 0) { - mxlock |= (1<<RTAX_RTT); - NEXT_ARG(); - } - if (get_unsigned(&rtt, *argv, 0)) - invarg("\"rtt\" value is invalid\n", *argv); - rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTT, rtt); - } else if (matches(*argv, "window") == 0) { - unsigned win; - NEXT_ARG(); - if (strcmp(*argv, "lock") == 0) { - mxlock |= (1<<RTAX_WINDOW); - NEXT_ARG(); - } - if (get_unsigned(&win, *argv, 0)) - invarg("\"window\" value is invalid\n", *argv); - rta_addattr32(mxrta, sizeof(mxbuf), RTAX_WINDOW, win); - } else if (matches(*argv, "cwnd") == 0) { - unsigned win; - NEXT_ARG(); - if (strcmp(*argv, "lock") == 0) { - mxlock |= (1<<RTAX_CWND); - NEXT_ARG(); - } - if (get_unsigned(&win, *argv, 0)) - invarg("\"cwnd\" value is invalid\n", *argv); - rta_addattr32(mxrta, sizeof(mxbuf), RTAX_CWND, win); - } else if (matches(*argv, "rttvar") == 0) { - unsigned win; - NEXT_ARG(); - if (strcmp(*argv, "lock") == 0) { - mxlock |= (1<<RTAX_RTTVAR); - NEXT_ARG(); - } - if (get_unsigned(&win, *argv, 0)) - invarg("\"rttvar\" value is invalid\n", *argv); - rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTTVAR, win); - } else if (matches(*argv, "ssthresh") == 0) { - unsigned win; - NEXT_ARG(); - if (strcmp(*argv, "lock") == 0) { - mxlock |= (1<<RTAX_SSTHRESH); - NEXT_ARG(); - } - if (get_unsigned(&win, *argv, 0)) - invarg("\"ssthresh\" value is invalid\n", *argv); - rta_addattr32(mxrta, sizeof(mxbuf), RTAX_SSTHRESH, win); - } else if (matches(*argv, "realms") == 0) { - __u32 realm; - NEXT_ARG(); - if (get_rt_realms(&realm, *argv)) - invarg("\"realm\" value is invalid\n", *argv); - addattr32(&req.n, sizeof(req), RTA_FLOW, realm); - } else if (strcmp(*argv, "onlink") == 0) { - req.r.rtm_flags |= RTNH_F_ONLINK; - } else if (matches(*argv, "equalize") == 0 || - strcmp(*argv, "eql") == 0) { - req.r.rtm_flags |= RTM_F_EQUALIZE; - } else if (strcmp(*argv, "nexthop") == 0) { - nhs_ok = 1; - break; - } else if (matches(*argv, "protocol") == 0) { - __u32 prot; - NEXT_ARG(); - if (rtnl_rtprot_a2n(&prot, *argv)) - invarg("\"protocol\" value is invalid\n", *argv); - req.r.rtm_protocol = prot; - proto_ok =1; - } else if (matches(*argv, "table") == 0) { - __u32 tid; - NEXT_ARG(); - if (rtnl_rttable_a2n(&tid, *argv)) - invarg("\"table\" value is invalid\n", *argv); - req.r.rtm_table = tid; - table_ok = 1; - } else if (strcmp(*argv, "dev") == 0 || - strcmp(*argv, "oif") == 0) { - NEXT_ARG(); - d = *argv; - } else if (strcmp(*argv, "mpath") == 0 || - strcmp(*argv, "mp") == 0) { - int i; - __u32 mp_alg = IP_MP_ALG_NONE; - - NEXT_ARG(); - for (i = 1; i < ARRAY_SIZE(mp_alg_names); i++) - if (strcmp(*argv, mp_alg_names[i]) == 0) - mp_alg = i; - if (mp_alg == IP_MP_ALG_NONE) - invarg("\"mpath\" value is invalid\n", *argv); - addattr_l(&req.n, sizeof(req), RTA_MP_ALGO, &mp_alg, sizeof(mp_alg)); - } else { - int type; - inet_prefix dst; - - if (strcmp(*argv, "to") == 0) { - NEXT_ARG(); - } - if ((**argv < '0' || **argv > '9') && - rtnl_rtntype_a2n(&type, *argv) == 0) { - NEXT_ARG(); - req.r.rtm_type = type; - type_ok = 1; - } - - if (matches(*argv, "help") == 0) - usage(); - if (dst_ok) - duparg2("to", *argv); - get_prefix(&dst, *argv, req.r.rtm_family); - if (req.r.rtm_family == AF_UNSPEC) - req.r.rtm_family = dst.family; - req.r.rtm_dst_len = dst.bitlen; - dst_ok = 1; - if (dst.bytelen) - addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); - } - argc--; argv++; - } - - if (d || nhs_ok) { - int idx; - - ll_init_map(&rth); - - if (d) { - if ((idx = ll_name_to_index(d)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return -1; - } - addattr32(&req.n, sizeof(req), RTA_OIF, idx); - } - } - - if (mxrta->rta_len > RTA_LENGTH(0)) { - if (mxlock) - rta_addattr32(mxrta, sizeof(mxbuf), RTAX_LOCK, mxlock); - addattr_l(&req.n, sizeof(req), RTA_METRICS, RTA_DATA(mxrta), RTA_PAYLOAD(mxrta)); - } - - if (nhs_ok) - parse_nexthops(&req.n, &req.r, argc, argv); - - if (!table_ok) { - if (req.r.rtm_type == RTN_LOCAL || - req.r.rtm_type == RTN_BROADCAST || - req.r.rtm_type == RTN_NAT || - req.r.rtm_type == RTN_ANYCAST) - req.r.rtm_table = RT_TABLE_LOCAL; - } - if (!scope_ok) { - if (req.r.rtm_type == RTN_LOCAL || - req.r.rtm_type == RTN_NAT) - req.r.rtm_scope = RT_SCOPE_HOST; - else if (req.r.rtm_type == RTN_BROADCAST || - req.r.rtm_type == RTN_MULTICAST || - req.r.rtm_type == RTN_ANYCAST) - req.r.rtm_scope = RT_SCOPE_LINK; - else if (req.r.rtm_type == RTN_UNICAST || - req.r.rtm_type == RTN_UNSPEC) { - if (cmd == RTM_DELROUTE) - req.r.rtm_scope = RT_SCOPE_NOWHERE; - else if (!gw_ok && !nhs_ok) - req.r.rtm_scope = RT_SCOPE_LINK; - } - } - - if (req.r.rtm_family == AF_UNSPEC) - req.r.rtm_family = AF_INET; - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - exit(2); - - return 0; -} - -static int rtnl_rtcache_request(struct rtnl_handle *rth, int family) -{ - struct { - struct nlmsghdr nlh; - struct rtmsg rtm; - } req; - struct sockaddr_nl nladdr; - - memset(&nladdr, 0, sizeof(nladdr)); - memset(&req, 0, sizeof(req)); - nladdr.nl_family = AF_NETLINK; - - req.nlh.nlmsg_len = sizeof(req); - req.nlh.nlmsg_type = RTM_GETROUTE; - req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_REQUEST; - req.nlh.nlmsg_pid = 0; - req.nlh.nlmsg_seq = rth->dump = ++rth->seq; - req.rtm.rtm_family = family; - req.rtm.rtm_flags |= RTM_F_CLONED; - - return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); -} - -static int iproute_flush_cache(void) -{ -#define ROUTE_FLUSH_PATH "/proc/sys/net/ipv4/route/flush" - - int len; - int flush_fd = open (ROUTE_FLUSH_PATH, O_WRONLY); - char *buffer = "-1"; - - if (flush_fd < 0) { - fprintf (stderr, "Cannot open \"%s\"\n", ROUTE_FLUSH_PATH); - return -1; - } - - len = strlen (buffer); - - if ((write (flush_fd, (void *)buffer, len)) < len) { - fprintf (stderr, "Cannot flush routing cache\n"); - return -1; - } - close(flush_fd); - return 0; -} - - -static int iproute_list_or_flush(int argc, char **argv, int flush) -{ - int do_ipv6 = preferred_family; - char *id = NULL; - char *od = NULL; - - iproute_reset_filter(); - filter.tb = RT_TABLE_MAIN; - - if (flush && argc <= 0) { - fprintf(stderr, "\"ip route flush\" requires arguments.\n"); - return -1; - } - - while (argc > 0) { - if (matches(*argv, "table") == 0) { - __u32 tid; - NEXT_ARG(); - if (rtnl_rttable_a2n(&tid, *argv)) { - if (strcmp(*argv, "all") == 0) { - tid = 0; - } else if (strcmp(*argv, "cache") == 0) { - tid = -1; - } else if (strcmp(*argv, "help") == 0) { - usage(); - } else { - invarg("table id value is invalid\n", *argv); - } - } - filter.tb = tid; - } else if (matches(*argv, "cached") == 0 || - matches(*argv, "cloned") == 0) { - filter.tb = -1; - } else if (strcmp(*argv, "tos") == 0 || - matches(*argv, "dsfield") == 0) { - __u32 tos; - NEXT_ARG(); - if (rtnl_dsfield_a2n(&tos, *argv)) - invarg("TOS value is invalid\n", *argv); - filter.tos = tos; - filter.tosmask = -1; - } else if (matches(*argv, "protocol") == 0) { - __u32 prot = 0; - NEXT_ARG(); - filter.protocolmask = -1; - if (rtnl_rtprot_a2n(&prot, *argv)) { - if (strcmp(*argv, "all") != 0) - invarg("invalid \"protocol\"\n", *argv); - prot = 0; - filter.protocolmask = 0; - } - filter.protocol = prot; - } else if (matches(*argv, "scope") == 0) { - __u32 scope = 0; - NEXT_ARG(); - filter.scopemask = -1; - if (rtnl_rtscope_a2n(&scope, *argv)) { - if (strcmp(*argv, "all") != 0) - invarg("invalid \"scope\"\n", *argv); - scope = RT_SCOPE_NOWHERE; - filter.scopemask = 0; - } - filter.scope = scope; - } else if (matches(*argv, "type") == 0) { - int type; - NEXT_ARG(); - filter.typemask = -1; - if (rtnl_rtntype_a2n(&type, *argv)) - invarg("node type value is invalid\n", *argv); - filter.type = type; - } else if (strcmp(*argv, "dev") == 0 || - strcmp(*argv, "oif") == 0) { - NEXT_ARG(); - od = *argv; - } else if (strcmp(*argv, "iif") == 0) { - NEXT_ARG(); - id = *argv; - } else if (strcmp(*argv, "via") == 0) { - NEXT_ARG(); - get_prefix(&filter.rvia, *argv, do_ipv6); - } else if (strcmp(*argv, "src") == 0) { - NEXT_ARG(); - get_prefix(&filter.rprefsrc, *argv, do_ipv6); - } else if (matches(*argv, "realms") == 0) { - __u32 realm; - NEXT_ARG(); - if (get_rt_realms(&realm, *argv)) - invarg("invalid realms\n", *argv); - filter.realm = realm; - filter.realmmask = ~0U; - if ((filter.realm&0xFFFF) == 0 && - (*argv)[strlen(*argv) - 1] == '/') - filter.realmmask &= ~0xFFFF; - if ((filter.realm&0xFFFF0000U) == 0 && - (strchr(*argv, '/') == NULL || - (*argv)[0] == '/')) - filter.realmmask &= ~0xFFFF0000U; - } else if (matches(*argv, "from") == 0) { - NEXT_ARG(); - if (matches(*argv, "root") == 0) { - NEXT_ARG(); - get_prefix(&filter.rsrc, *argv, do_ipv6); - } else if (matches(*argv, "match") == 0) { - NEXT_ARG(); - get_prefix(&filter.msrc, *argv, do_ipv6); - } else { - if (matches(*argv, "exact") == 0) { - NEXT_ARG(); - } - get_prefix(&filter.msrc, *argv, do_ipv6); - filter.rsrc = filter.msrc; - } - } else { - if (matches(*argv, "to") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "root") == 0) { - NEXT_ARG(); - get_prefix(&filter.rdst, *argv, do_ipv6); - } else if (matches(*argv, "match") == 0) { - NEXT_ARG(); - get_prefix(&filter.mdst, *argv, do_ipv6); - } else { - if (matches(*argv, "exact") == 0) { - NEXT_ARG(); - } - get_prefix(&filter.mdst, *argv, do_ipv6); - filter.rdst = filter.mdst; - } - } - argc--; argv++; - } - - if (do_ipv6 == AF_UNSPEC && filter.tb) - do_ipv6 = AF_INET; - - ll_init_map(&rth); - - if (id || od) { - int idx; - - if (id) { - if ((idx = ll_name_to_index(id)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", id); - return -1; - } - filter.iif = idx; - filter.iifmask = -1; - } - if (od) { - if ((idx = ll_name_to_index(od)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", od); - return -1; - } - filter.oif = idx; - filter.oifmask = -1; - } - } - - if (flush) { - int round = 0; - char flushb[4096-512]; - time_t start = time(0); - - if (filter.tb == -1) { - if (do_ipv6 != AF_INET6) { - iproute_flush_cache(); - if (show_stats) - printf("*** IPv4 routing cache is flushed.\n"); - } - if (do_ipv6 == AF_INET) - return 0; - } - - filter.flushb = flushb; - filter.flushp = 0; - filter.flushe = sizeof(flushb); - - for (;;) { - if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { - perror("Cannot send dump request"); - exit(1); - } - filter.flushed = 0; - if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Flush terminated\n"); - exit(1); - } - if (filter.flushed == 0) { - if (round == 0) { - if (filter.tb != -1 || do_ipv6 == AF_INET6) - fprintf(stderr, "Nothing to flush.\n"); - } else if (show_stats) - printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":""); - fflush(stdout); - return 0; - } - round++; - if (flush_update() < 0) - exit(1); - - if (time(0) - start > 30) { - printf("\n*** Flush not completed after %ld seconds, %d entries remain ***\n", - time(0) - start, filter.flushed); - exit(1); - } - - if (show_stats) { - printf("\n*** Round %d, deleting %d entries ***\n", round, filter.flushed); - fflush(stdout); - } - } - } - - if (filter.tb != -1) { - if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { - perror("Cannot send dump request"); - exit(1); - } - } else { - if (rtnl_rtcache_request(&rth, do_ipv6) < 0) { - perror("Cannot send dump request"); - exit(1); - } - } - - if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - exit(1); - } - - exit(0); -} - - -int iproute_get(int argc, char **argv) -{ - struct { - struct nlmsghdr n; - struct rtmsg r; - char buf[1024]; - } req; - char *idev = NULL; - char *odev = NULL; - int connected = 0; - int from_ok = 0; - - memset(&req, 0, sizeof(req)); - - iproute_reset_filter(); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST; - req.n.nlmsg_type = RTM_GETROUTE; - req.r.rtm_family = preferred_family; - req.r.rtm_table = 0; - req.r.rtm_protocol = 0; - req.r.rtm_scope = 0; - req.r.rtm_type = 0; - req.r.rtm_src_len = 0; - req.r.rtm_dst_len = 0; - req.r.rtm_tos = 0; - - while (argc > 0) { - if (strcmp(*argv, "tos") == 0 || - matches(*argv, "dsfield") == 0) { - __u32 tos; - NEXT_ARG(); - if (rtnl_dsfield_a2n(&tos, *argv)) - invarg("TOS value is invalid\n", *argv); - req.r.rtm_tos = tos; - } else if (matches(*argv, "from") == 0) { - inet_prefix addr; - NEXT_ARG(); - if (matches(*argv, "help") == 0) - usage(); - from_ok = 1; - get_prefix(&addr, *argv, req.r.rtm_family); - if (req.r.rtm_family == AF_UNSPEC) - req.r.rtm_family = addr.family; - if (addr.bytelen) - addattr_l(&req.n, sizeof(req), RTA_SRC, &addr.data, addr.bytelen); - req.r.rtm_src_len = addr.bitlen; - } else if (matches(*argv, "iif") == 0) { - NEXT_ARG(); - idev = *argv; - } else if (matches(*argv, "oif") == 0 || - strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - odev = *argv; - } else if (matches(*argv, "notify") == 0) { - req.r.rtm_flags |= RTM_F_NOTIFY; - } else if (matches(*argv, "connected") == 0) { - connected = 1; - } else { - inet_prefix addr; - if (strcmp(*argv, "to") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "help") == 0) - usage(); - get_prefix(&addr, *argv, req.r.rtm_family); - if (req.r.rtm_family == AF_UNSPEC) - req.r.rtm_family = addr.family; - if (addr.bytelen) - addattr_l(&req.n, sizeof(req), RTA_DST, &addr.data, addr.bytelen); - req.r.rtm_dst_len = addr.bitlen; - } - argc--; argv++; - } - - if (req.r.rtm_dst_len == 0) { - fprintf(stderr, "need at least destination address\n"); - exit(1); - } - - ll_init_map(&rth); - - if (idev || odev) { - int idx; - - if (idev) { - if ((idx = ll_name_to_index(idev)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", idev); - return -1; - } - addattr32(&req.n, sizeof(req), RTA_IIF, idx); - } - if (odev) { - if ((idx = ll_name_to_index(odev)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", odev); - return -1; - } - addattr32(&req.n, sizeof(req), RTA_OIF, idx); - } - } - - if (req.r.rtm_family == AF_UNSPEC) - req.r.rtm_family = AF_INET; - - if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) - exit(2); - - if (connected && !from_ok) { - struct rtmsg *r = NLMSG_DATA(&req.n); - int len = req.n.nlmsg_len; - struct rtattr * tb[RTA_MAX+1]; - - if (print_route(NULL, &req.n, (void*)stdout) < 0) { - fprintf(stderr, "An error :-)\n"); - exit(1); - } - - if (req.n.nlmsg_type != RTM_NEWROUTE) { - fprintf(stderr, "Not a route?\n"); - return -1; - } - len -= NLMSG_LENGTH(sizeof(*r)); - if (len < 0) { - fprintf(stderr, "Wrong len %d\n", len); - return -1; - } - - parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); - - if (tb[RTA_PREFSRC]) { - tb[RTA_PREFSRC]->rta_type = RTA_SRC; - r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]); - } else if (!tb[RTA_SRC]) { - fprintf(stderr, "Failed to connect the route\n"); - return -1; - } - if (!odev && tb[RTA_OIF]) - tb[RTA_OIF]->rta_type = 0; - if (tb[RTA_GATEWAY]) - tb[RTA_GATEWAY]->rta_type = 0; - if (!idev && tb[RTA_IIF]) - tb[RTA_IIF]->rta_type = 0; - req.n.nlmsg_flags = NLM_F_REQUEST; - req.n.nlmsg_type = RTM_GETROUTE; - - if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) - exit(2); - } - - if (print_route(NULL, &req.n, (void*)stdout) < 0) { - fprintf(stderr, "An error :-)\n"); - exit(1); - } - - exit(0); -} - -void iproute_reset_filter() -{ - memset(&filter, 0, sizeof(filter)); - filter.mdst.bitlen = -1; - filter.msrc.bitlen = -1; -} - -int do_iproute(int argc, char **argv) -{ - if (argc < 1) - return iproute_list_or_flush(0, NULL, 0); - - if (matches(*argv, "add") == 0) - return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE|NLM_F_EXCL, - argc-1, argv+1); - if (matches(*argv, "change") == 0 || strcmp(*argv, "chg") == 0) - return iproute_modify(RTM_NEWROUTE, NLM_F_REPLACE, - argc-1, argv+1); - if (matches(*argv, "replace") == 0) - return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE|NLM_F_REPLACE, - argc-1, argv+1); - if (matches(*argv, "prepend") == 0) - return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE, - argc-1, argv+1); - if (matches(*argv, "append") == 0) - return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE|NLM_F_APPEND, - argc-1, argv+1); - if (matches(*argv, "test") == 0) - return iproute_modify(RTM_NEWROUTE, NLM_F_EXCL, - argc-1, argv+1); - if (matches(*argv, "delete") == 0) - return iproute_modify(RTM_DELROUTE, 0, - argc-1, argv+1); - if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 - || matches(*argv, "lst") == 0) - return iproute_list_or_flush(argc-1, argv+1, 0); - if (matches(*argv, "get") == 0) - return iproute_get(argc-1, argv+1); - if (matches(*argv, "flush") == 0) - return iproute_list_or_flush(argc-1, argv+1, 1); - if (matches(*argv, "help") == 0) - usage(); - fprintf(stderr, "Command \"%s\" is unknown, try \"ip route help\".\n", *argv); - exit(-1); -} - diff --git a/ip/iprule.c b/ip/iprule.c deleted file mode 100644 index ccf699f..0000000 --- a/ip/iprule.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * iprule.c "ip rule". - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - * - * Changes: - * - * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <arpa/inet.h> -#include <string.h> - -#include "rt_names.h" -#include "utils.h" - -extern struct rtnl_handle rth; - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, "Usage: ip rule [ list | add | del | flush ] SELECTOR ACTION\n"); - fprintf(stderr, "SELECTOR := [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK ]\n"); - fprintf(stderr, " [ dev STRING ] [ pref NUMBER ]\n"); - fprintf(stderr, "ACTION := [ table TABLE_ID ]\n"); - fprintf(stderr, " [ prohibit | reject | unreachable ]\n"); - fprintf(stderr, " [ realms [SRCREALM/]DSTREALM ]\n"); - fprintf(stderr, "TABLE_ID := [ local | main | default | NUMBER ]\n"); - exit(-1); -} - -static int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, - void *arg) -{ - FILE *fp = (FILE*)arg; - struct rtmsg *r = NLMSG_DATA(n); - int len = n->nlmsg_len; - int host_len = -1; - struct rtattr * tb[RTA_MAX+1]; - char abuf[256]; - SPRINT_BUF(b1); - - if (n->nlmsg_type != RTM_NEWRULE) - return 0; - - len -= NLMSG_LENGTH(sizeof(*r)); - if (len < 0) - return -1; - - parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); - - if (r->rtm_family == AF_INET) - host_len = 32; - else if (r->rtm_family == AF_INET6) - host_len = 128; - else if (r->rtm_family == AF_DECnet) - host_len = 16; - else if (r->rtm_family == AF_IPX) - host_len = 80; - - if (tb[RTA_PRIORITY]) - fprintf(fp, "%u:\t", *(unsigned*)RTA_DATA(tb[RTA_PRIORITY])); - else - fprintf(fp, "0:\t"); - - if (tb[RTA_SRC]) { - if (r->rtm_src_len != host_len) { - fprintf(fp, "from %s/%u ", rt_addr_n2a(r->rtm_family, - RTA_PAYLOAD(tb[RTA_SRC]), - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)), - r->rtm_src_len - ); - } else { - fprintf(fp, "from %s ", format_host(r->rtm_family, - RTA_PAYLOAD(tb[RTA_SRC]), - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)) - ); - } - } else if (r->rtm_src_len) { - fprintf(fp, "from 0/%d ", r->rtm_src_len); - } else { - fprintf(fp, "from all "); - } - - if (tb[RTA_DST]) { - if (r->rtm_dst_len != host_len) { - fprintf(fp, "to %s/%u ", rt_addr_n2a(r->rtm_family, - RTA_PAYLOAD(tb[RTA_DST]), - RTA_DATA(tb[RTA_DST]), - abuf, sizeof(abuf)), - r->rtm_dst_len - ); - } else { - fprintf(fp, "to %s ", format_host(r->rtm_family, - RTA_PAYLOAD(tb[RTA_DST]), - RTA_DATA(tb[RTA_DST]), - abuf, sizeof(abuf))); - } - } else if (r->rtm_dst_len) { - fprintf(fp, "to 0/%d ", r->rtm_dst_len); - } - - if (r->rtm_tos) { - SPRINT_BUF(b1); - fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1))); - } - if (tb[RTA_PROTOINFO]) { - fprintf(fp, "fwmark %#x ", *(__u32*)RTA_DATA(tb[RTA_PROTOINFO])); - } - - if (tb[RTA_IIF]) { - fprintf(fp, "iif %s ", (char*)RTA_DATA(tb[RTA_IIF])); - } - - if (r->rtm_table) - fprintf(fp, "lookup %s ", rtnl_rttable_n2a(r->rtm_table, b1, sizeof(b1))); - - if (tb[RTA_FLOW]) { - __u32 to = *(__u32*)RTA_DATA(tb[RTA_FLOW]); - __u32 from = to>>16; - to &= 0xFFFF; - if (from) { - fprintf(fp, "realms %s/", - rtnl_rtrealm_n2a(from, b1, sizeof(b1))); - } - fprintf(fp, "%s ", - rtnl_rtrealm_n2a(to, b1, sizeof(b1))); - } - - if (r->rtm_type == RTN_NAT) { - if (tb[RTA_GATEWAY]) { - fprintf(fp, "map-to %s ", - format_host(r->rtm_family, - RTA_PAYLOAD(tb[RTA_GATEWAY]), - RTA_DATA(tb[RTA_GATEWAY]), - abuf, sizeof(abuf))); - } else - fprintf(fp, "masquerade"); - } else if (r->rtm_type != RTN_UNICAST) - fprintf(fp, "%s", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1))); - - fprintf(fp, "\n"); - fflush(fp); - return 0; -} - -static int iprule_list(int argc, char **argv) -{ - int af = preferred_family; - - if (af == AF_UNSPEC) - af = AF_INET; - - if (argc > 0) { - fprintf(stderr, "\"ip rule show\" does not take any arguments.\n"); - return -1; - } - - if (rtnl_wilddump_request(&rth, af, RTM_GETRULE) < 0) { - perror("Cannot send dump request"); - return 1; - } - - if (rtnl_dump_filter(&rth, print_rule, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - return 1; - } - - return 0; -} - - -static int iprule_modify(int cmd, int argc, char **argv) -{ - int table_ok = 0; - struct { - struct nlmsghdr n; - struct rtmsg r; - char buf[1024]; - } req; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_type = cmd; - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST; - req.r.rtm_family = preferred_family; - req.r.rtm_protocol = RTPROT_BOOT; - req.r.rtm_scope = RT_SCOPE_UNIVERSE; - req.r.rtm_table = 0; - req.r.rtm_type = RTN_UNSPEC; - - if (cmd == RTM_NEWRULE) { - req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL; - req.r.rtm_type = RTN_UNICAST; - } - - while (argc > 0) { - if (strcmp(*argv, "from") == 0) { - inet_prefix dst; - NEXT_ARG(); - get_prefix(&dst, *argv, req.r.rtm_family); - req.r.rtm_src_len = dst.bitlen; - addattr_l(&req.n, sizeof(req), RTA_SRC, &dst.data, dst.bytelen); - } else if (strcmp(*argv, "to") == 0) { - inet_prefix dst; - NEXT_ARG(); - get_prefix(&dst, *argv, req.r.rtm_family); - req.r.rtm_dst_len = dst.bitlen; - addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); - } else if (matches(*argv, "preference") == 0 || - matches(*argv, "order") == 0 || - matches(*argv, "priority") == 0) { - __u32 pref; - NEXT_ARG(); - if (get_u32(&pref, *argv, 0)) - invarg("preference value is invalid\n", *argv); - addattr32(&req.n, sizeof(req), RTA_PRIORITY, pref); - } else if (strcmp(*argv, "tos") == 0) { - __u32 tos; - NEXT_ARG(); - if (rtnl_dsfield_a2n(&tos, *argv)) - invarg("TOS value is invalid\n", *argv); - req.r.rtm_tos = tos; - } else if (strcmp(*argv, "fwmark") == 0) { - __u32 fwmark; - NEXT_ARG(); - if (get_u32(&fwmark, *argv, 0)) - invarg("fwmark value is invalid\n", *argv); - addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark); - } else if (matches(*argv, "realms") == 0) { - __u32 realm; - NEXT_ARG(); - if (get_rt_realms(&realm, *argv)) - invarg("invalid realms\n", *argv); - addattr32(&req.n, sizeof(req), RTA_FLOW, realm); - } else if (matches(*argv, "table") == 0 || - strcmp(*argv, "lookup") == 0) { - __u32 tid; - NEXT_ARG(); - if (rtnl_rttable_a2n(&tid, *argv)) - invarg("invalid table ID\n", *argv); - req.r.rtm_table = tid; - table_ok = 1; - } else if (strcmp(*argv, "dev") == 0 || - strcmp(*argv, "iif") == 0) { - NEXT_ARG(); - addattr_l(&req.n, sizeof(req), RTA_IIF, *argv, strlen(*argv)+1); - } else if (strcmp(*argv, "nat") == 0 || - matches(*argv, "map-to") == 0) { - NEXT_ARG(); - fprintf(stderr, "Warning: route NAT is deprecated\n"); - addattr32(&req.n, sizeof(req), RTA_GATEWAY, get_addr32(*argv)); - req.r.rtm_type = RTN_NAT; - } else { - int type; - - if (strcmp(*argv, "type") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "help") == 0) - usage(); - if (rtnl_rtntype_a2n(&type, *argv)) - invarg("Failed to parse rule type", *argv); - req.r.rtm_type = type; - } - argc--; - argv++; - } - - if (req.r.rtm_family == AF_UNSPEC) - req.r.rtm_family = AF_INET; - - if (!table_ok && cmd == RTM_NEWRULE) - req.r.rtm_table = RT_TABLE_MAIN; - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - return 2; - - return 0; -} - - -static int flush_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) -{ - struct rtnl_handle rth2; - struct rtmsg *r = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr * tb[RTA_MAX+1]; - - len -= NLMSG_LENGTH(sizeof(*r)); - if (len < 0) - return -1; - - parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); - - if (tb[RTA_PRIORITY]) { - n->nlmsg_type = RTM_DELRULE; - n->nlmsg_flags = NLM_F_REQUEST; - - if (rtnl_open(&rth2, 0) < 0) - return -1; - - if (rtnl_talk(&rth2, n, 0, 0, NULL, NULL, NULL) < 0) - return -2; - - rtnl_close(&rth2); - } - - return 0; -} - -static int iprule_flush(int argc, char **argv) -{ - int af = preferred_family; - - if (af == AF_UNSPEC) - af = AF_INET; - - if (argc > 0) { - fprintf(stderr, "\"ip rule flush\" does not allow arguments\n"); - return -1; - } - - if (rtnl_wilddump_request(&rth, af, RTM_GETRULE) < 0) { - perror("Cannot send dump request"); - return 1; - } - - if (rtnl_dump_filter(&rth, flush_rule, NULL, NULL, NULL) < 0) { - fprintf(stderr, "Flush terminated\n"); - return 1; - } - - return 0; -} - -int do_iprule(int argc, char **argv) -{ - if (argc < 1) { - return iprule_list(0, NULL); - } else if (matches(argv[0], "list") == 0 || - matches(argv[0], "lst") == 0 || - matches(argv[0], "show") == 0) { - return iprule_list(argc-1, argv+1); - } else if (matches(argv[0], "add") == 0) { - return iprule_modify(RTM_NEWRULE, argc-1, argv+1); - } else if (matches(argv[0], "delete") == 0) { - return iprule_modify(RTM_DELRULE, argc-1, argv+1); - } else if (matches(argv[0], "flush") == 0) { - return iprule_flush(argc-1, argv+1); - } else if (matches(argv[0], "help") == 0) - usage(); - - fprintf(stderr, "Command \"%s\" is unknown, try \"ip rule help\".\n", *argv); - exit(-1); -} - diff --git a/ip/iptunnel.c b/ip/iptunnel.c deleted file mode 100644 index 2da3df1..0000000 --- a/ip/iptunnel.c +++ /dev/null @@ -1,585 +0,0 @@ -/* - * iptunnel.c "ip tunnel" - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - * - * Changes: - * - * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses - * Rani Assaf <rani@magic.metawire.com> 980930: do not allow key for ipip/sit - * Phil Karn <karn@ka9q.ampr.org> 990408: "pmtudisc" flag - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/ioctl.h> -#include <linux/if.h> -#include <linux/if_arp.h> -#include <linux/ip.h> - -#ifndef __constant_htons -#define __constant_htons(x) htons(x) -#endif - -#include <linux/if_tunnel.h> - -#include "rt_names.h" -#include "utils.h" - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, "Usage: ip tunnel { add | change | del | show } [ NAME ]\n"); - fprintf(stderr, " [ mode { ipip | gre | sit } ] [ remote ADDR ] [ local ADDR ]\n"); - fprintf(stderr, " [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n"); - fprintf(stderr, " [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "Where: NAME := STRING\n"); - fprintf(stderr, " ADDR := { IP_ADDRESS | any }\n"); - fprintf(stderr, " TOS := { NUMBER | inherit }\n"); - fprintf(stderr, " TTL := { 1..255 | inherit }\n"); - fprintf(stderr, " KEY := { DOTTED_QUAD | NUMBER }\n"); - exit(-1); -} - -static int do_ioctl_get_ifindex(const char *dev) -{ - struct ifreq ifr; - int fd; - int err; - - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - fd = socket(AF_INET, SOCK_DGRAM, 0); - err = ioctl(fd, SIOCGIFINDEX, &ifr); - if (err) { - perror("ioctl"); - return 0; - } - close(fd); - return ifr.ifr_ifindex; -} - -static int do_ioctl_get_iftype(const char *dev) -{ - struct ifreq ifr; - int fd; - int err; - - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - fd = socket(AF_INET, SOCK_DGRAM, 0); - err = ioctl(fd, SIOCGIFHWADDR, &ifr); - if (err) { - perror("ioctl"); - return -1; - } - close(fd); - return ifr.ifr_addr.sa_family; -} - - -static char * do_ioctl_get_ifname(int idx) -{ - static struct ifreq ifr; - int fd; - int err; - - ifr.ifr_ifindex = idx; - fd = socket(AF_INET, SOCK_DGRAM, 0); - err = ioctl(fd, SIOCGIFNAME, &ifr); - if (err) { - perror("ioctl"); - return NULL; - } - close(fd); - return ifr.ifr_name; -} - - -static int do_get_ioctl(const char *basedev, struct ip_tunnel_parm *p) -{ - struct ifreq ifr; - int fd; - int err; - - strncpy(ifr.ifr_name, basedev, IFNAMSIZ); - ifr.ifr_ifru.ifru_data = (void*)p; - fd = socket(AF_INET, SOCK_DGRAM, 0); - err = ioctl(fd, SIOCGETTUNNEL, &ifr); - if (err) - perror("ioctl"); - close(fd); - return err; -} - -static int do_add_ioctl(int cmd, const char *basedev, struct ip_tunnel_parm *p) -{ - struct ifreq ifr; - int fd; - int err; - - if (cmd == SIOCCHGTUNNEL && p->name[0]) - strncpy(ifr.ifr_name, p->name, IFNAMSIZ); - else - strncpy(ifr.ifr_name, basedev, IFNAMSIZ); - ifr.ifr_ifru.ifru_data = (void*)p; - fd = socket(AF_INET, SOCK_DGRAM, 0); - err = ioctl(fd, cmd, &ifr); - if (err) - perror("ioctl"); - close(fd); - return err; -} - -static int do_del_ioctl(const char *basedev, struct ip_tunnel_parm *p) -{ - struct ifreq ifr; - int fd; - int err; - - if (p->name[0]) - strncpy(ifr.ifr_name, p->name, IFNAMSIZ); - else - strncpy(ifr.ifr_name, basedev, IFNAMSIZ); - ifr.ifr_ifru.ifru_data = (void*)p; - fd = socket(AF_INET, SOCK_DGRAM, 0); - err = ioctl(fd, SIOCDELTUNNEL, &ifr); - if (err) - perror("ioctl"); - close(fd); - return err; -} - -static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) -{ - int count = 0; - char medium[IFNAMSIZ]; - - memset(p, 0, sizeof(*p)); - memset(&medium, 0, sizeof(medium)); - - p->iph.version = 4; - p->iph.ihl = 5; -#ifndef IP_DF -#define IP_DF 0x4000 /* Flag: "Don't Fragment" */ -#endif - p->iph.frag_off = htons(IP_DF); - - while (argc > 0) { - if (strcmp(*argv, "mode") == 0) { - NEXT_ARG(); - if (strcmp(*argv, "ipip") == 0 || - strcmp(*argv, "ip/ip") == 0) { - if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) { - fprintf(stderr,"You managed to ask for more than one tunnel mode.\n"); - exit(-1); - } - p->iph.protocol = IPPROTO_IPIP; - } else if (strcmp(*argv, "gre") == 0 || - strcmp(*argv, "gre/ip") == 0) { - if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) { - fprintf(stderr,"You managed to ask for more than one tunnel mode.\n"); - exit(-1); - } - p->iph.protocol = IPPROTO_GRE; - } else if (strcmp(*argv, "sit") == 0 || - strcmp(*argv, "ipv6/ip") == 0) { - if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) { - fprintf(stderr,"You managed to ask for more than one tunnel mode.\n"); - exit(-1); - } - p->iph.protocol = IPPROTO_IPV6; - } else { - fprintf(stderr,"Cannot guess tunnel mode.\n"); - exit(-1); - } - } else if (strcmp(*argv, "key") == 0) { - unsigned uval; - NEXT_ARG(); - p->i_flags |= GRE_KEY; - p->o_flags |= GRE_KEY; - if (strchr(*argv, '.')) - p->i_key = p->o_key = get_addr32(*argv); - else { - if (get_unsigned(&uval, *argv, 0)<0) { - fprintf(stderr, "invalid value of \"key\"\n"); - exit(-1); - } - p->i_key = p->o_key = htonl(uval); - } - } else if (strcmp(*argv, "ikey") == 0) { - unsigned uval; - NEXT_ARG(); - p->i_flags |= GRE_KEY; - if (strchr(*argv, '.')) - p->o_key = get_addr32(*argv); - else { - if (get_unsigned(&uval, *argv, 0)<0) { - fprintf(stderr, "invalid value of \"ikey\"\n"); - exit(-1); - } - p->i_key = htonl(uval); - } - } else if (strcmp(*argv, "okey") == 0) { - unsigned uval; - NEXT_ARG(); - p->o_flags |= GRE_KEY; - if (strchr(*argv, '.')) - p->o_key = get_addr32(*argv); - else { - if (get_unsigned(&uval, *argv, 0)<0) { - fprintf(stderr, "invalid value of \"okey\"\n"); - exit(-1); - } - p->o_key = htonl(uval); - } - } else if (strcmp(*argv, "seq") == 0) { - p->i_flags |= GRE_SEQ; - p->o_flags |= GRE_SEQ; - } else if (strcmp(*argv, "iseq") == 0) { - p->i_flags |= GRE_SEQ; - } else if (strcmp(*argv, "oseq") == 0) { - p->o_flags |= GRE_SEQ; - } else if (strcmp(*argv, "csum") == 0) { - p->i_flags |= GRE_CSUM; - p->o_flags |= GRE_CSUM; - } else if (strcmp(*argv, "icsum") == 0) { - p->i_flags |= GRE_CSUM; - } else if (strcmp(*argv, "ocsum") == 0) { - p->o_flags |= GRE_CSUM; - } else if (strcmp(*argv, "nopmtudisc") == 0) { - p->iph.frag_off = 0; - } else if (strcmp(*argv, "pmtudisc") == 0) { - p->iph.frag_off = htons(IP_DF); - } else if (strcmp(*argv, "remote") == 0) { - NEXT_ARG(); - if (strcmp(*argv, "any")) - p->iph.daddr = get_addr32(*argv); - } else if (strcmp(*argv, "local") == 0) { - NEXT_ARG(); - if (strcmp(*argv, "any")) - p->iph.saddr = get_addr32(*argv); - } else if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - strncpy(medium, *argv, IFNAMSIZ-1); - } else if (strcmp(*argv, "ttl") == 0) { - unsigned uval; - NEXT_ARG(); - if (strcmp(*argv, "inherit") != 0) { - if (get_unsigned(&uval, *argv, 0)) - invarg("invalid TTL\n", *argv); - if (uval > 255) - invarg("TTL must be <=255\n", *argv); - p->iph.ttl = uval; - } - } else if (strcmp(*argv, "tos") == 0 || - matches(*argv, "dsfield") == 0) { - __u32 uval; - NEXT_ARG(); - if (strcmp(*argv, "inherit") != 0) { - if (rtnl_dsfield_a2n(&uval, *argv)) - invarg("bad TOS value", *argv); - p->iph.tos = uval; - } else - p->iph.tos = 1; - } else { - if (strcmp(*argv, "name") == 0) { - NEXT_ARG(); - } - if (matches(*argv, "help") == 0) - usage(); - if (p->name[0]) - duparg2("name", *argv); - strncpy(p->name, *argv, IFNAMSIZ); - if (cmd == SIOCCHGTUNNEL && count == 0) { - struct ip_tunnel_parm old_p; - memset(&old_p, 0, sizeof(old_p)); - if (do_get_ioctl(*argv, &old_p)) - return -1; - *p = old_p; - } - } - count++; - argc--; argv++; - } - - - if (p->iph.protocol == 0) { - if (memcmp(p->name, "gre", 3) == 0) - p->iph.protocol = IPPROTO_GRE; - else if (memcmp(p->name, "ipip", 4) == 0) - p->iph.protocol = IPPROTO_IPIP; - else if (memcmp(p->name, "sit", 3) == 0) - p->iph.protocol = IPPROTO_IPV6; - } - - if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) { - if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) { - fprintf(stderr, "Keys are not allowed with ipip and sit.\n"); - return -1; - } - } - - if (medium[0]) { - p->link = do_ioctl_get_ifindex(medium); - if (p->link == 0) - return -1; - } - - if (p->i_key == 0 && IN_MULTICAST(ntohl(p->iph.daddr))) { - p->i_key = p->iph.daddr; - p->i_flags |= GRE_KEY; - } - if (p->o_key == 0 && IN_MULTICAST(ntohl(p->iph.daddr))) { - p->o_key = p->iph.daddr; - p->o_flags |= GRE_KEY; - } - if (IN_MULTICAST(ntohl(p->iph.daddr)) && !p->iph.saddr) { - fprintf(stderr, "Broadcast tunnel requires a source address.\n"); - return -1; - } - return 0; -} - - -static int do_add(int cmd, int argc, char **argv) -{ - struct ip_tunnel_parm p; - - if (parse_args(argc, argv, cmd, &p) < 0) - return -1; - - if (p.iph.ttl && p.iph.frag_off == 0) { - fprintf(stderr, "ttl != 0 and noptmudisc are incompatible\n"); - return -1; - } - - switch (p.iph.protocol) { - case IPPROTO_IPIP: - return do_add_ioctl(cmd, "tunl0", &p); - case IPPROTO_GRE: - return do_add_ioctl(cmd, "gre0", &p); - case IPPROTO_IPV6: - return do_add_ioctl(cmd, "sit0", &p); - default: - fprintf(stderr, "cannot determine tunnel mode (ipip, gre or sit)\n"); - return -1; - } - return -1; -} - -int do_del(int argc, char **argv) -{ - struct ip_tunnel_parm p; - - if (parse_args(argc, argv, SIOCDELTUNNEL, &p) < 0) - return -1; - - switch (p.iph.protocol) { - case IPPROTO_IPIP: - return do_del_ioctl("tunl0", &p); - case IPPROTO_GRE: - return do_del_ioctl("gre0", &p); - case IPPROTO_IPV6: - return do_del_ioctl("sit0", &p); - default: - return do_del_ioctl(p.name, &p); - } - return -1; -} - -void print_tunnel(struct ip_tunnel_parm *p) -{ - char s1[1024]; - char s2[1024]; - char s3[64]; - char s4[64]; - - inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3)); - inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4)); - - /* Do not use format_host() for local addr, - * symbolic name will not be useful. - */ - printf("%s: %s/ip remote %s local %s ", - p->name, - p->iph.protocol == IPPROTO_IPIP ? "ip" : - (p->iph.protocol == IPPROTO_GRE ? "gre" : - (p->iph.protocol == IPPROTO_IPV6 ? "ipv6" : "unknown")), - p->iph.daddr ? format_host(AF_INET, 4, &p->iph.daddr, s1, sizeof(s1)) : "any", - p->iph.saddr ? rt_addr_n2a(AF_INET, 4, &p->iph.saddr, s2, sizeof(s2)) : "any"); - - if (p->link) { - char *n = do_ioctl_get_ifname(p->link); - if (n) - printf(" dev %s ", n); - } - - if (p->iph.ttl) - printf(" ttl %d ", p->iph.ttl); - else - printf(" ttl inherit "); - - if (p->iph.tos) { - SPRINT_BUF(b1); - printf(" tos"); - if (p->iph.tos&1) - printf(" inherit"); - if (p->iph.tos&~1) - printf("%c%s ", p->iph.tos&1 ? '/' : ' ', - rtnl_dsfield_n2a(p->iph.tos&~1, b1, sizeof(b1))); - } - - if (!(p->iph.frag_off&htons(IP_DF))) - printf(" nopmtudisc"); - - if ((p->i_flags&GRE_KEY) && (p->o_flags&GRE_KEY) && p->o_key == p->i_key) - printf(" key %s", s3); - else if ((p->i_flags|p->o_flags)&GRE_KEY) { - if (p->i_flags&GRE_KEY) - printf(" ikey %s ", s3); - if (p->o_flags&GRE_KEY) - printf(" okey %s ", s4); - } - - if (p->i_flags&GRE_SEQ) - printf("%s Drop packets out of sequence.\n", _SL_); - if (p->i_flags&GRE_CSUM) - printf("%s Checksum in received packet is required.", _SL_); - if (p->o_flags&GRE_SEQ) - printf("%s Sequence packets on output.", _SL_); - if (p->o_flags&GRE_CSUM) - printf("%s Checksum output packets.", _SL_); -} - -static int do_tunnels_list(struct ip_tunnel_parm *p) -{ - char name[IFNAMSIZ]; - unsigned long rx_bytes, rx_packets, rx_errs, rx_drops, - rx_fifo, rx_frame, - tx_bytes, tx_packets, tx_errs, tx_drops, - tx_fifo, tx_colls, tx_carrier, rx_multi; - int type; - struct ip_tunnel_parm p1; - - char buf[512]; - FILE *fp = fopen("/proc/net/dev", "r"); - if (fp == NULL) { - perror("fopen"); - return -1; - } - - fgets(buf, sizeof(buf), fp); - fgets(buf, sizeof(buf), fp); - - while (fgets(buf, sizeof(buf), fp) != NULL) { - char *ptr; - buf[sizeof(buf) - 1] = 0; - if ((ptr = strchr(buf, ':')) == NULL || - (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) { - fprintf(stderr, "Wrong format of /proc/net/dev. Sorry.\n"); - return -1; - } - if (sscanf(ptr, "%ld%ld%ld%ld%ld%ld%ld%*d%ld%ld%ld%ld%ld%ld%ld", - &rx_bytes, &rx_packets, &rx_errs, &rx_drops, - &rx_fifo, &rx_frame, &rx_multi, - &tx_bytes, &tx_packets, &tx_errs, &tx_drops, - &tx_fifo, &tx_colls, &tx_carrier) != 14) - continue; - if (p->name[0] && strcmp(p->name, name)) - continue; - type = do_ioctl_get_iftype(name); - if (type == -1) { - fprintf(stderr, "Failed to get type of [%s]\n", name); - continue; - } - if (type != ARPHRD_TUNNEL && type != ARPHRD_IPGRE && type != ARPHRD_SIT) - continue; - memset(&p1, 0, sizeof(p1)); - if (do_get_ioctl(name, &p1)) - continue; - if ((p->link && p1.link != p->link) || - (p->name[0] && strcmp(p1.name, p->name)) || - (p->iph.daddr && p1.iph.daddr != p->iph.daddr) || - (p->iph.saddr && p1.iph.saddr != p->iph.saddr) || - (p->i_key && p1.i_key != p->i_key)) - continue; - print_tunnel(&p1); - if (show_stats) { - printf("%s", _SL_); - printf("RX: Packets Bytes Errors CsumErrs OutOfSeq Mcasts%s", _SL_); - printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-8ld%s", - rx_packets, rx_bytes, rx_errs, rx_frame, rx_fifo, rx_multi, _SL_); - printf("TX: Packets Bytes Errors DeadLoop NoRoute NoBufs%s", _SL_); - printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-6ld", - tx_packets, tx_bytes, tx_errs, tx_colls, tx_carrier, tx_drops); - } - printf("\n"); - } - return 0; -} - -static int do_show(int argc, char **argv) -{ - int err; - struct ip_tunnel_parm p; - - if (parse_args(argc, argv, SIOCGETTUNNEL, &p) < 0) - return -1; - - switch (p.iph.protocol) { - case IPPROTO_IPIP: - err = do_get_ioctl(p.name[0] ? p.name : "tunl0", &p); - break; - case IPPROTO_GRE: - err = do_get_ioctl(p.name[0] ? p.name : "gre0", &p); - break; - case IPPROTO_IPV6: - err = do_get_ioctl(p.name[0] ? p.name : "sit0", &p); - break; - default: - do_tunnels_list(&p); - return 0; - } - if (err) - return -1; - - print_tunnel(&p); - printf("\n"); - return 0; -} - -int do_iptunnel(int argc, char **argv) -{ - if (argc > 0) { - if (matches(*argv, "add") == 0) - return do_add(SIOCADDTUNNEL, argc-1, argv+1); - if (matches(*argv, "change") == 0) - return do_add(SIOCCHGTUNNEL, argc-1, argv+1); - if (matches(*argv, "del") == 0) - return do_del(argc-1, argv+1); - if (matches(*argv, "show") == 0 || - matches(*argv, "lst") == 0 || - matches(*argv, "list") == 0) - return do_show(argc-1, argv+1); - if (matches(*argv, "help") == 0) - usage(); - } else - return do_show(0, NULL); - - fprintf(stderr, "Command \"%s\" is unknown, try \"ip tunnel help\".\n", *argv); - exit(-1); -} diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c deleted file mode 100644 index 8baaabd..0000000 --- a/ip/ipxfrm.c +++ /dev/null @@ -1,1185 +0,0 @@ -/* $USAGI: $ */ - -/* - * Copyright (C)2004 USAGI/WIDE Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -/* - * based on ip.c, iproute.c - */ -/* - * Authors: - * Masahide NAKAMURA @USAGI - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <time.h> -#include <netdb.h> -#include <net/if.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <linux/xfrm.h> - -#include "utils.h" -#include "xfrm.h" - -#define STRBUF_SIZE (128) -#define STRBUF_CAT(buf, str) \ - do { \ - int rest = sizeof(buf) - 1 - strlen(buf); \ - if (rest > 0) { \ - int len = strlen(str); \ - if (len > rest) \ - len = rest; \ - strncat(buf, str, len); \ - buf[sizeof(buf) - 1] = '\0'; \ - } \ - } while(0); - -struct xfrm_filter filter; - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, - "Usage: ip xfrm XFRM_OBJECT { COMMAND | help }\n" - "where XFRM_OBJECT := { state | policy | monitor }\n"); - exit(-1); -} - -/* This is based on utils.c(inet_addr_match) */ -int xfrm_addr_match(xfrm_address_t *x1, xfrm_address_t *x2, int bits) -{ - __u32 *a1 = (__u32 *)x1; - __u32 *a2 = (__u32 *)x2; - int words = bits >> 0x05; - - bits &= 0x1f; - - if (words) - if (memcmp(a1, a2, words << 2)) - return -1; - - if (bits) { - __u32 w1, w2; - __u32 mask; - - w1 = a1[words]; - w2 = a2[words]; - - mask = htonl((0xffffffff) << (0x20 - bits)); - - if ((w1 ^ w2) & mask) - return 1; - } - - return 0; -} - -struct typeent { - const char *t_name; - int t_type; -}; - -static const struct typeent xfrmproto_types[]= { - { "esp", IPPROTO_ESP }, { "ah", IPPROTO_AH }, { "comp", IPPROTO_COMP }, - { NULL, -1 } -}; - -int xfrm_xfrmproto_getbyname(char *name) -{ - int i; - - for (i = 0; ; i++) { - const struct typeent *t = &xfrmproto_types[i]; - if (!t->t_name || t->t_type == -1) - break; - - if (strcmp(t->t_name, name) == 0) - return t->t_type; - } - - return -1; -} - -const char *strxf_xfrmproto(__u8 proto) -{ - int i; - - for (i = 0; ; i++) { - const struct typeent *t = &xfrmproto_types[i]; - if (!t->t_name || t->t_type == -1) - break; - - if (t->t_type == proto) - return t->t_name; - } - - return NULL; -} - -static const struct typeent algo_types[]= { - { "enc", XFRMA_ALG_CRYPT }, { "auth", XFRMA_ALG_AUTH }, - { "comp", XFRMA_ALG_COMP }, { NULL, -1 } -}; - -int xfrm_algotype_getbyname(char *name) -{ - int i; - - for (i = 0; ; i++) { - const struct typeent *t = &algo_types[i]; - if (!t->t_name || t->t_type == -1) - break; - - if (strcmp(t->t_name, name) == 0) - return t->t_type; - } - - return -1; -} - -const char *strxf_algotype(int type) -{ - int i; - - for (i = 0; ; i++) { - const struct typeent *t = &algo_types[i]; - if (!t->t_name || t->t_type == -1) - break; - - if (t->t_type == type) - return t->t_name; - } - - return NULL; -} - -const char *strxf_mask8(__u8 mask) -{ - static char str[16]; - const int sn = sizeof(mask) * 8 - 1; - __u8 b; - int i = 0; - - for (b = (1 << sn); b > 0; b >>= 1) - str[i++] = ((b & mask) ? '1' : '0'); - str[i] = '\0'; - - return str; -} - -const char *strxf_mask32(__u32 mask) -{ - static char str[16]; - - sprintf(str, "%.8x", mask); - - return str; -} - -const char *strxf_share(__u8 share) -{ - static char str[32]; - - switch (share) { - case XFRM_SHARE_ANY: - strcpy(str, "any"); - break; - case XFRM_SHARE_SESSION: - strcpy(str, "session"); - break; - case XFRM_SHARE_USER: - strcpy(str, "user"); - break; - case XFRM_SHARE_UNIQUE: - strcpy(str, "unique"); - break; - default: - sprintf(str, "%u", share); - break; - } - - return str; -} - -const char *strxf_proto(__u8 proto) -{ - static char buf[32]; - struct protoent *pp; - const char *p; - - pp = getprotobynumber(proto); - if (pp) - p = pp->p_name; - else { - sprintf(buf, "%u", proto); - p = buf; - } - - return p; -} - -void xfrm_id_info_print(xfrm_address_t *saddr, struct xfrm_id *id, - __u8 mode, __u32 reqid, __u16 family, int force_spi, - FILE *fp, const char *prefix, const char *title) -{ - char abuf[256]; - - if (title) - fprintf(fp, title); - - memset(abuf, '\0', sizeof(abuf)); - fprintf(fp, "src %s ", rt_addr_n2a(family, sizeof(*saddr), - saddr, abuf, sizeof(abuf))); - memset(abuf, '\0', sizeof(abuf)); - fprintf(fp, "dst %s", rt_addr_n2a(family, sizeof(id->daddr), - &id->daddr, abuf, sizeof(abuf))); - fprintf(fp, "%s", _SL_); - - if (prefix) - fprintf(fp, prefix); - fprintf(fp, "\t"); - - fprintf(fp, "proto %s ", strxf_xfrmproto(id->proto)); - - if (show_stats > 0 || force_spi || id->spi) { - __u32 spi = ntohl(id->spi); - fprintf(fp, "spi 0x%08x", spi); - if (show_stats > 0) - fprintf(fp, "(%u)", spi); - fprintf(fp, " "); - } - - fprintf(fp, "reqid %u", reqid); - if (show_stats > 0) - fprintf(fp, "(0x%08x)", reqid); - fprintf(fp, " "); - - fprintf(fp, "mode "); - switch (mode) { - case 0: - fprintf(fp, "transport"); - break; - case 1: - fprintf(fp, "tunnel"); - break; - default: - fprintf(fp, "%u", mode); - break; - } - fprintf(fp, "%s", _SL_); -} - -static const char *strxf_limit(__u64 limit) -{ - static char str[32]; - if (limit == XFRM_INF) - strcpy(str, "(INF)"); - else - sprintf(str, "%llu", (unsigned long long) limit); - - return str; -} - -void xfrm_stats_print(struct xfrm_stats *s, FILE *fp, const char *prefix) -{ - if (prefix) - fprintf(fp, prefix); - fprintf(fp, "stats:"); - fprintf(fp, "%s", _SL_); - - if (prefix) - fprintf(fp, prefix); - fprintf(fp, " "); - fprintf(fp, "replay-window %u ", s->replay_window); - fprintf(fp, "replay %u ", s->replay); - fprintf(fp, "failed %u", s->integrity_failed); - fprintf(fp, "%s", _SL_); -} - -static const char *strxf_time(__u64 time) -{ - static char str[32]; - - if (time == 0) - strcpy(str, "-"); - else { - time_t t; - struct tm *tp; - - /* XXX: treat time in the same manner of kernel's - * net/xfrm/xfrm_{user,state}.c - */ - t = (long)time; - tp = localtime(&t); - - strftime(str, sizeof(str), "%Y-%m-%d %T", tp); - } - - return str; -} - -void xfrm_lifetime_print(struct xfrm_lifetime_cfg *cfg, - struct xfrm_lifetime_cur *cur, - FILE *fp, const char *prefix) -{ - if (cfg) { - if (prefix) - fprintf(fp, prefix); - fprintf(fp, "lifetime config:"); - fprintf(fp, "%s", _SL_); - - if (prefix) - fprintf(fp, prefix); - fprintf(fp, " "); - fprintf(fp, "limit: "); - fprintf(fp, "soft "); - fprintf(fp, strxf_limit(cfg->soft_byte_limit)); - fprintf(fp, "(bytes), hard "); - fprintf(fp, strxf_limit(cfg->hard_byte_limit)); - fprintf(fp, "(bytes)"); - fprintf(fp, "%s", _SL_); - - if (prefix) - fprintf(fp, prefix); - fprintf(fp, " "); - fprintf(fp, "limit: "); - fprintf(fp, "soft "); - fprintf(fp, strxf_limit(cfg->soft_packet_limit)); - fprintf(fp, "(packets), hard "); - fprintf(fp, strxf_limit(cfg->hard_packet_limit)); - fprintf(fp, "(packets)"); - fprintf(fp, "%s", _SL_); - - if (prefix) - fprintf(fp, prefix); - fprintf(fp, " "); - fprintf(fp, "expire add: "); - fprintf(fp, "soft "); - fprintf(fp, "%llu", (unsigned long long) cfg->soft_add_expires_seconds); - fprintf(fp, "(sec), hard "); - fprintf(fp, "%llu", (unsigned long long) cfg->hard_add_expires_seconds); - fprintf(fp, "(sec)"); - fprintf(fp, "%s", _SL_); - - if (prefix) - fprintf(fp, prefix); - fprintf(fp, " "); - fprintf(fp, "expire use: "); - fprintf(fp, "soft "); - fprintf(fp, "%llu", (unsigned long long) cfg->soft_use_expires_seconds); - fprintf(fp, "(sec), hard "); - fprintf(fp, "%llu", (unsigned long long) cfg->hard_use_expires_seconds); - fprintf(fp, "(sec)"); - fprintf(fp, "%s", _SL_); - } - if (cur) { - if (prefix) - fprintf(fp, prefix); - fprintf(fp, "lifetime current:"); - fprintf(fp, "%s", _SL_); - - if (prefix) - fprintf(fp, prefix); - fprintf(fp, " "); - fprintf(fp, "%llu(bytes), ", (unsigned long long) cur->bytes); - fprintf(fp, "%llu(packets)", (unsigned long long) cur->packets); - fprintf(fp, "%s", _SL_); - - if (prefix) - fprintf(fp, prefix); - fprintf(fp, " "); - fprintf(fp, "add %s ", strxf_time(cur->add_time)); - fprintf(fp, "use %s", strxf_time(cur->use_time)); - fprintf(fp, "%s", _SL_); - } -} - -void xfrm_selector_print(struct xfrm_selector *sel, __u16 family, - FILE *fp, const char *prefix) -{ - char abuf[256]; - __u16 f; - - f = sel->family; - if (f == AF_UNSPEC) - f = family; - if (f == AF_UNSPEC) - f = preferred_family; - - if (prefix) - fprintf(fp, prefix); - - memset(abuf, '\0', sizeof(abuf)); - fprintf(fp, "src %s/%u ", rt_addr_n2a(f, sizeof(sel->saddr), - &sel->saddr, abuf, sizeof(abuf)), - sel->prefixlen_s); - - memset(abuf, '\0', sizeof(abuf)); - fprintf(fp, "dst %s/%u ", rt_addr_n2a(f, sizeof(sel->daddr), - &sel->daddr, abuf, sizeof(abuf)), - sel->prefixlen_d); - - if (sel->proto) - fprintf(fp, "proto %s ", strxf_proto(sel->proto)); - switch (sel->proto) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_SCTP: - case IPPROTO_DCCP: - default: /* XXX */ - if (sel->sport_mask) - fprintf(fp, "sport %u ", ntohs(sel->sport)); - if (sel->dport_mask) - fprintf(fp, "dport %u ", ntohs(sel->dport)); - break; - case IPPROTO_ICMP: - case IPPROTO_ICMPV6: - /* type/code is stored at sport/dport in selector */ - if (sel->sport_mask) - fprintf(fp, "type %u ", ntohs(sel->sport)); - if (sel->dport_mask) - fprintf(fp, "code %u ", ntohs(sel->dport)); - break; - } - - if (sel->ifindex > 0) { - char buf[IFNAMSIZ]; - - memset(buf, '\0', sizeof(buf)); - if_indextoname(sel->ifindex, buf); - fprintf(fp, "dev %s ", buf); - } - - if (show_stats > 0) - fprintf(fp, "uid %u", sel->user); - - fprintf(fp, "%s", _SL_); -} - -static void xfrm_algo_print(struct xfrm_algo *algo, int type, int len, - FILE *fp, const char *prefix) -{ - int keylen; - int i; - - if (prefix) - fprintf(fp, prefix); - - fprintf(fp, "%s ", strxf_algotype(type)); - - if (len < sizeof(*algo)) { - fprintf(fp, "(ERROR truncated)"); - goto fin; - } - len -= sizeof(*algo); - - fprintf(fp, "%s ", algo->alg_name); - - keylen = algo->alg_key_len / 8; - if (len < keylen) { - fprintf(fp, "(ERROR truncated)"); - goto fin; - } - - fprintf(fp, "0x"); - for (i = 0; i < keylen; i ++) - fprintf(fp, "%.2x", (unsigned char)algo->alg_key[i]); - - if (show_stats > 0) - fprintf(fp, " (%d bits)", algo->alg_key_len); - - fin: - fprintf(fp, "%s", _SL_); -} - -static void xfrm_tmpl_print(struct xfrm_user_tmpl *tmpls, int len, - __u16 family, FILE *fp, const char *prefix) -{ - int ntmpls = len / sizeof(struct xfrm_user_tmpl); - int i; - - if (ntmpls <= 0) { - if (prefix) - fprintf(fp, prefix); - fprintf(fp, "(ERROR \"tmpl\" truncated)"); - fprintf(fp, "%s", _SL_); - return; - } - - for (i = 0; i < ntmpls; i++) { - struct xfrm_user_tmpl *tmpl = &tmpls[i]; - - if (prefix) - fprintf(fp, prefix); - - xfrm_id_info_print(&tmpl->saddr, &tmpl->id, tmpl->mode, - tmpl->reqid, family, 0, fp, prefix, "tmpl "); - - if (show_stats > 0 || tmpl->optional) { - if (prefix) - fprintf(fp, prefix); - fprintf(fp, "\t"); - switch (tmpl->optional) { - case 0: - if (show_stats > 0) - fprintf(fp, "level required "); - break; - case 1: - fprintf(fp, "level use "); - break; - default: - fprintf(fp, "level %u ", tmpl->optional); - break; - } - - if (show_stats > 0) - fprintf(fp, "share %s ", strxf_share(tmpl->share)); - - fprintf(fp, "%s", _SL_); - } - - if (show_stats > 0) { - if (prefix) - fprintf(fp, prefix); - fprintf(fp, "\t"); - fprintf(fp, "%s-mask %s ", - strxf_algotype(XFRMA_ALG_CRYPT), - strxf_mask32(tmpl->ealgos)); - fprintf(fp, "%s-mask %s ", - strxf_algotype(XFRMA_ALG_AUTH), - strxf_mask32(tmpl->aalgos)); - fprintf(fp, "%s-mask %s", - strxf_algotype(XFRMA_ALG_COMP), - strxf_mask32(tmpl->calgos)); - - fprintf(fp, "%s", _SL_); - } - } -} - -void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, - FILE *fp, const char *prefix) -{ - if (tb[XFRMA_ALG_AUTH]) { - struct rtattr *rta = tb[XFRMA_ALG_AUTH]; - xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta), - XFRMA_ALG_AUTH, RTA_PAYLOAD(rta), fp, prefix); - } - - if (tb[XFRMA_ALG_CRYPT]) { - struct rtattr *rta = tb[XFRMA_ALG_CRYPT]; - xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta), - XFRMA_ALG_CRYPT, RTA_PAYLOAD(rta), fp, prefix); - } - - if (tb[XFRMA_ALG_COMP]) { - struct rtattr *rta = tb[XFRMA_ALG_COMP]; - xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta), - XFRMA_ALG_COMP, RTA_PAYLOAD(rta), fp, prefix); - } - - if (tb[XFRMA_ENCAP]) { - struct xfrm_encap_tmpl *e; - char abuf[256]; - - if (prefix) - fprintf(fp, prefix); - fprintf(fp, "encap "); - - if (RTA_PAYLOAD(tb[XFRMA_ENCAP]) < sizeof(*e)) { - fprintf(fp, "(ERROR truncated)"); - fprintf(fp, "%s", _SL_); - return; - } - e = (struct xfrm_encap_tmpl *) RTA_DATA(tb[XFRMA_ENCAP]); - - fprintf(fp, "type "); - switch (e->encap_type) { - case 1: - fprintf(fp, "espinudp-nonike "); - break; - case 2: - fprintf(fp, "espinudp "); - break; - default: - fprintf(fp, "%u ", e->encap_type); - break; - } - fprintf(fp, "sport %u ", ntohs(e->encap_sport)); - fprintf(fp, "dport %u ", ntohs(e->encap_dport)); - - memset(abuf, '\0', sizeof(abuf)); - fprintf(fp, "addr %s", - rt_addr_n2a(family, sizeof(e->encap_oa), - &e->encap_oa, abuf, sizeof(abuf))); - fprintf(fp, "%s", _SL_); - } - - if (tb[XFRMA_TMPL]) { - struct rtattr *rta = tb[XFRMA_TMPL]; - xfrm_tmpl_print((struct xfrm_user_tmpl *) RTA_DATA(rta), - RTA_PAYLOAD(rta), family, fp, prefix); - } -} - -static int xfrm_selector_iszero(struct xfrm_selector *s) -{ - struct xfrm_selector s0; - - memset(&s0, 0, sizeof(s0)); - - return (memcmp(&s0, s, sizeof(s0)) == 0); -} - -void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo, - struct rtattr *tb[], FILE *fp, const char *prefix, - const char *title) -{ - char buf[STRBUF_SIZE]; - - memset(buf, '\0', sizeof(buf)); - - xfrm_id_info_print(&xsinfo->saddr, &xsinfo->id, xsinfo->mode, - xsinfo->reqid, xsinfo->family, 1, fp, prefix, - title); - - if (prefix) - STRBUF_CAT(buf, prefix); - STRBUF_CAT(buf, "\t"); - - fprintf(fp, buf); - fprintf(fp, "replay-window %u ", xsinfo->replay_window); - if (show_stats > 0) - fprintf(fp, "seq 0x%08u ", xsinfo->seq); - if (show_stats > 0 || xsinfo->flags) { - __u8 flags = xsinfo->flags; - - fprintf(fp, "flag "); - XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_NOECN, "noecn"); - XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_DECAP_DSCP, "decap-dscp"); - if (flags) - fprintf(fp, "%x", flags); - if (show_stats > 0) - fprintf(fp, " (0x%s)", strxf_mask8(flags)); - } - fprintf(fp, "%s", _SL_); - - xfrm_xfrma_print(tb, xsinfo->family, fp, buf); - - if (!xfrm_selector_iszero(&xsinfo->sel)) { - char sbuf[STRBUF_SIZE]; - - memcpy(sbuf, buf, sizeof(sbuf)); - STRBUF_CAT(sbuf, "sel "); - - xfrm_selector_print(&xsinfo->sel, xsinfo->family, fp, sbuf); - } - - if (show_stats > 0) { - xfrm_lifetime_print(&xsinfo->lft, &xsinfo->curlft, fp, buf); - xfrm_stats_print(&xsinfo->stats, fp, buf); - } -} - -void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo, - struct rtattr *tb[], FILE *fp, const char *prefix, - const char *title) -{ - char buf[STRBUF_SIZE]; - - memset(buf, '\0', sizeof(buf)); - - xfrm_selector_print(&xpinfo->sel, preferred_family, fp, title); - - if (prefix) - STRBUF_CAT(buf, prefix); - STRBUF_CAT(buf, "\t"); - - fprintf(fp, buf); - fprintf(fp, "dir "); - switch (xpinfo->dir) { - case XFRM_POLICY_IN: - fprintf(fp, "in"); - break; - case XFRM_POLICY_OUT: - fprintf(fp, "out"); - break; - case XFRM_POLICY_FWD: - fprintf(fp, "fwd"); - break; - default: - fprintf(fp, "%u", xpinfo->dir); - break; - } - fprintf(fp, " "); - - switch (xpinfo->action) { - case XFRM_POLICY_ALLOW: - if (show_stats > 0) - fprintf(fp, "action allow "); - break; - case XFRM_POLICY_BLOCK: - fprintf(fp, "action block "); - break; - default: - fprintf(fp, "action %u ", xpinfo->action); - break; - } - - if (show_stats) - fprintf(fp, "index %u ", xpinfo->index); - fprintf(fp, "priority %u ", xpinfo->priority); - if (show_stats > 0) { - fprintf(fp, "share %s ", strxf_share(xpinfo->share)); - fprintf(fp, "flag 0x%s", strxf_mask8(xpinfo->flags)); - } - fprintf(fp, "%s", _SL_); - - if (show_stats > 0) - xfrm_lifetime_print(&xpinfo->lft, &xpinfo->curlft, fp, buf); - - xfrm_xfrma_print(tb, xpinfo->sel.family, fp, buf); -} - -int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family, - int loose, int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - inet_prefix dst; - inet_prefix src; - - memset(&dst, 0, sizeof(dst)); - memset(&src, 0, sizeof(src)); - - while (1) { - if (strcmp(*argv, "src") == 0) { - NEXT_ARG(); - - get_prefix(&src, *argv, preferred_family); - if (src.family == AF_UNSPEC) - invarg("\"src\" address family is AF_UNSPEC", *argv); - if (family) - *family = src.family; - - memcpy(saddr, &src.data, sizeof(*saddr)); - - filter.id_src_mask = src.bitlen; - - } else if (strcmp(*argv, "dst") == 0) { - NEXT_ARG(); - - get_prefix(&dst, *argv, preferred_family); - if (dst.family == AF_UNSPEC) - invarg("\"dst\" address family is AF_UNSPEC", *argv); - if (family) - *family = dst.family; - - memcpy(&id->daddr, &dst.data, sizeof(id->daddr)); - - filter.id_dst_mask = dst.bitlen; - - } else if (strcmp(*argv, "proto") == 0) { - int ret; - - NEXT_ARG(); - - ret = xfrm_xfrmproto_getbyname(*argv); - if (ret < 0) - invarg("\"XFRM_PROTO\" is invalid", *argv); - - id->proto = (__u8)ret; - - filter.id_proto_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "spi") == 0) { - __u32 spi; - - NEXT_ARG(); - if (get_u32(&spi, *argv, 0)) - invarg("\"SPI\" is invalid", *argv); - - spi = htonl(spi); - id->spi = spi; - - filter.id_spi_mask = XFRM_FILTER_MASK_FULL; - - } else { - PREV_ARG(); /* back track */ - break; - } - - if (!NEXT_ARG_OK()) - break; - NEXT_ARG(); - } - - if (src.family && dst.family && (src.family != dst.family)) - invarg("the same address family is required between \"src\" and \"dst\"", *argv); - - if (loose == 0 && id->proto == 0) - missarg("XFRM_PROTO"); - if (argc == *argcp) - missarg("ID"); - - *argcp = argc; - *argvp = argv; - - return 0; -} - -int xfrm_mode_parse(__u8 *mode, int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - - if (matches(*argv, "transport") == 0) - *mode = 0; - else if (matches(*argv, "tunnel") == 0) - *mode = 1; - else - invarg("\"MODE\" is invalid", *argv); - - *argcp = argc; - *argvp = argv; - - return 0; -} - -int xfrm_encap_type_parse(__u16 *type, int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - - if (strcmp(*argv, "espinudp-nonike") == 0) - *type = 1; - else if (strcmp(*argv, "espinudp") == 0) - *type = 2; - else - invarg("\"ENCAP-TYPE\" is invalid", *argv); - - *argcp = argc; - *argvp = argv; - - return 0; -} - -/* NOTE: reqid is used by host-byte order */ -int xfrm_reqid_parse(__u32 *reqid, int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - - if (get_u32(reqid, *argv, 0)) - invarg("\"REQID\" is invalid", *argv); - - *argcp = argc; - *argvp = argv; - - return 0; -} - -static int xfrm_selector_upspec_parse(struct xfrm_selector *sel, - int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - char *sportp = NULL; - char *dportp = NULL; - char *typep = NULL; - char *codep = NULL; - - while (1) { - if (strcmp(*argv, "proto") == 0) { - __u8 upspec; - - NEXT_ARG(); - - if (strcmp(*argv, "any") == 0) - upspec = 0; - else { - struct protoent *pp; - pp = getprotobyname(*argv); - if (pp) - upspec = pp->p_proto; - else { - if (get_u8(&upspec, *argv, 0)) - invarg("\"PROTO\" is invalid", *argv); - } - } - sel->proto = upspec; - - filter.upspec_proto_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "sport") == 0) { - sportp = *argv; - - NEXT_ARG(); - - if (get_u16(&sel->sport, *argv, 0)) - invarg("\"PORT\" is invalid", *argv); - sel->sport = htons(sel->sport); - if (sel->sport) - sel->sport_mask = ~((__u16)0); - - filter.upspec_sport_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "dport") == 0) { - dportp = *argv; - - NEXT_ARG(); - - if (get_u16(&sel->dport, *argv, 0)) - invarg("\"PORT\" is invalid", *argv); - sel->dport = htons(sel->dport); - if (sel->dport) - sel->dport_mask = ~((__u16)0); - - filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "type") == 0) { - typep = *argv; - - NEXT_ARG(); - - if (get_u16(&sel->sport, *argv, 0) || - (sel->sport & ~((__u16)0xff))) - invarg("\"type\" value is invalid", *argv); - sel->sport = htons(sel->sport); - sel->sport_mask = ~((__u16)0); - - filter.upspec_sport_mask = XFRM_FILTER_MASK_FULL; - - - } else if (strcmp(*argv, "code") == 0) { - codep = *argv; - - NEXT_ARG(); - - if (get_u16(&sel->dport, *argv, 0) || - (sel->dport & ~((__u16)0xff))) - invarg("\"code\" value is invalid", *argv); - sel->dport = htons(sel->dport); - sel->dport_mask = ~((__u16)0); - - filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL; - - } else { - PREV_ARG(); /* back track */ - break; - } - - if (!NEXT_ARG_OK()) - break; - NEXT_ARG(); - } - if (argc == *argcp) - missarg("UPSPEC"); - if (sportp || dportp) { - switch (sel->proto) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_SCTP: - case IPPROTO_DCCP: - break; - default: - fprintf(stderr, "\"sport\" and \"dport\" are invalid with proto=%s\n", strxf_proto(sel->proto)); - exit(1); - } - } - if (typep || codep) { - switch (sel->proto) { - case IPPROTO_ICMP: - case IPPROTO_ICMPV6: - break; - default: - fprintf(stderr, "\"type\" and \"code\" are invalid with proto=%s\n", strxf_proto(sel->proto)); - exit(1); - } - } - - *argcp = argc; - *argvp = argv; - - return 0; -} - -int xfrm_selector_parse(struct xfrm_selector *sel, int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - inet_prefix dst; - inet_prefix src; - char *upspecp = NULL; - - memset(&dst, 0, sizeof(dst)); - memset(&src, 0, sizeof(src)); - - while (1) { - if (strcmp(*argv, "src") == 0) { - NEXT_ARG(); - - get_prefix(&src, *argv, preferred_family); - if (src.family == AF_UNSPEC) - invarg("\"src\" address family is AF_UNSPEC", *argv); - sel->family = src.family; - - memcpy(&sel->saddr, &src.data, sizeof(sel->saddr)); - sel->prefixlen_s = src.bitlen; - - filter.sel_src_mask = src.bitlen; - - } else if (strcmp(*argv, "dst") == 0) { - NEXT_ARG(); - - get_prefix(&dst, *argv, preferred_family); - if (dst.family == AF_UNSPEC) - invarg("\"dst\" address family is AF_UNSPEC", *argv); - sel->family = dst.family; - - memcpy(&sel->daddr, &dst.data, sizeof(sel->daddr)); - sel->prefixlen_d = dst.bitlen; - - filter.sel_dst_mask = dst.bitlen; - - } else if (strcmp(*argv, "dev") == 0) { - int ifindex; - - NEXT_ARG(); - - if (strcmp(*argv, "none") == 0) - ifindex = 0; - else { - ifindex = if_nametoindex(*argv); - if (ifindex <= 0) - invarg("\"DEV\" is invalid", *argv); - } - sel->ifindex = ifindex; - - filter.sel_dev_mask = XFRM_FILTER_MASK_FULL; - - } else { - if (upspecp) { - PREV_ARG(); /* back track */ - break; - } else { - upspecp = *argv; - xfrm_selector_upspec_parse(sel, &argc, &argv); - } - } - - if (!NEXT_ARG_OK()) - break; - - NEXT_ARG(); - } - - if (src.family && dst.family && (src.family != dst.family)) - invarg("the same address family is required between \"src\" and \"dst\"", *argv); - - if (argc == *argcp) - missarg("SELECTOR"); - - *argcp = argc; - *argvp = argv; - - return 0; -} - -int xfrm_lifetime_cfg_parse(struct xfrm_lifetime_cfg *lft, - int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - int ret; - - if (strcmp(*argv, "time-soft") == 0) { - NEXT_ARG(); - ret = get_u64(&lft->soft_add_expires_seconds, *argv, 0); - if (ret) - invarg("\"time-soft\" value is invalid", *argv); - } else if (strcmp(*argv, "time-hard") == 0) { - NEXT_ARG(); - ret = get_u64(&lft->hard_add_expires_seconds, *argv, 0); - if (ret) - invarg("\"time-hard\" value is invalid", *argv); - } else if (strcmp(*argv, "time-use-soft") == 0) { - NEXT_ARG(); - ret = get_u64(&lft->soft_use_expires_seconds, *argv, 0); - if (ret) - invarg("\"time-use-soft\" value is invalid", *argv); - } else if (strcmp(*argv, "time-use-hard") == 0) { - NEXT_ARG(); - ret = get_u64(&lft->hard_use_expires_seconds, *argv, 0); - if (ret) - invarg("\"time-use-hard\" value is invalid", *argv); - } else if (strcmp(*argv, "byte-soft") == 0) { - NEXT_ARG(); - ret = get_u64(&lft->soft_byte_limit, *argv, 0); - if (ret) - invarg("\"byte-soft\" value is invalid", *argv); - } else if (strcmp(*argv, "byte-hard") == 0) { - NEXT_ARG(); - ret = get_u64(&lft->hard_byte_limit, *argv, 0); - if (ret) - invarg("\"byte-hard\" value is invalid", *argv); - } else if (strcmp(*argv, "packet-soft") == 0) { - NEXT_ARG(); - ret = get_u64(&lft->soft_packet_limit, *argv, 0); - if (ret) - invarg("\"packet-soft\" value is invalid", *argv); - } else if (strcmp(*argv, "packet-hard") == 0) { - NEXT_ARG(); - ret = get_u64(&lft->hard_packet_limit, *argv, 0); - if (ret) - invarg("\"packet-hard\" value is invalid", *argv); - } else - invarg("\"LIMIT\" is invalid", *argv); - - *argcp = argc; - *argvp = argv; - - return 0; -} - -int do_xfrm(int argc, char **argv) -{ - memset(&filter, 0, sizeof(filter)); - - if (argc < 1) - usage(); - - if (matches(*argv, "state") == 0 || - matches(*argv, "sa") == 0) - return do_xfrm_state(argc-1, argv+1); - else if (matches(*argv, "policy") == 0) - return do_xfrm_policy(argc-1, argv+1); - else if (matches(*argv, "monitor") == 0) - return do_xfrm_monitor(argc-1, argv+1); - else if (matches(*argv, "help") == 0) { - usage(); - fprintf(stderr, "xfrm Object \"%s\" is unknown.\n", *argv); - exit(-1); - } - usage(); -} diff --git a/ip/routef b/ip/routef deleted file mode 100755 index db43b5d..0000000 --- a/ip/routef +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh - -exec ip -4 ro flush scope global type unicast diff --git a/ip/routel b/ip/routel deleted file mode 100755 index 8d1d352..0000000 --- a/ip/routel +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh -#$Id$ - -# -# Script created by: Stephen R. van den Berg <srb@cuci.nl>, 1999/04/18 -# Donated to the public domain. -# -# This script transforms the output of "ip" into more readable text. -# "ip" is the Linux-advanced-routing configuration tool part of the -# iproute package. -# - -test "X-h" = "X$1" && echo "Usage: $0 [tablenr [raw ip args...]]" && exit 64 - -test -z "$*" && set 0 - -ip route list table "$@" | - while read network rest - do set xx $rest - shift - proto="" - via="" - dev="" - scope="" - src="" - table="" - case $network in - broadcast|local|unreachable) via=$network - network=$1 - shift - ;; - esac - while test $# != 0 - do - key=$1 - val=$2 - eval "$key=$val" - shift 2 - done - echo "$network $via $src $proto $scope $dev $table" - done | awk -F ' ' ' -BEGIN { - format="%15s%-3s %15s %15s %8s %8s%7s %s\n"; - printf(format,"target","","gateway","source","proto","scope","dev","tbl"); - } - { network=$1; - mask=""; - if(match(network,"/")) - { mask=" "substr(network,RSTART+1); - network=substr(network,0,RSTART); - } - via=$2; - src=$3; - proto=$4; - scope=$5; - dev=$6; - table=$7; - printf(format,network,mask,via,src,proto,scope,dev,table); - } -' diff --git a/ip/rtm_map.c b/ip/rtm_map.c deleted file mode 100644 index 21e818b..0000000 --- a/ip/rtm_map.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * rtm_map.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <string.h> -#include <sys/socket.h> -#include <netinet/in.h> - -#include "rt_names.h" -#include "utils.h" - -char *rtnl_rtntype_n2a(int id, char *buf, int len) -{ - switch (id) { - case RTN_UNSPEC: - return "none"; - case RTN_UNICAST: - return "unicast"; - case RTN_LOCAL: - return "local"; - case RTN_BROADCAST: - return "broadcast"; - case RTN_ANYCAST: - return "anycast"; - case RTN_MULTICAST: - return "multicast"; - case RTN_BLACKHOLE: - return "blackhole"; - case RTN_UNREACHABLE: - return "unreachable"; - case RTN_PROHIBIT: - return "prohibit"; - case RTN_THROW: - return "throw"; - case RTN_NAT: - return "nat"; - case RTN_XRESOLVE: - return "xresolve"; - default: - snprintf(buf, len, "%d", id); - return buf; - } -} - - -int rtnl_rtntype_a2n(int *id, char *arg) -{ - char *end; - unsigned long res; - - if (strcmp(arg, "local") == 0) - res = RTN_LOCAL; - else if (strcmp(arg, "nat") == 0) - res = RTN_NAT; - else if (matches(arg, "broadcast") == 0 || - strcmp(arg, "brd") == 0) - res = RTN_BROADCAST; - else if (matches(arg, "anycast") == 0) - res = RTN_ANYCAST; - else if (matches(arg, "multicast") == 0) - res = RTN_MULTICAST; - else if (matches(arg, "prohibit") == 0) - res = RTN_PROHIBIT; - else if (matches(arg, "unreachable") == 0) - res = RTN_UNREACHABLE; - else if (matches(arg, "blackhole") == 0) - res = RTN_BLACKHOLE; - else if (matches(arg, "xresolve") == 0) - res = RTN_XRESOLVE; - else if (matches(arg, "unicast") == 0) - res = RTN_UNICAST; - else if (strcmp(arg, "throw") == 0) - res = RTN_THROW; - else { - res = strtoul(arg, &end, 0); - if (!end || end == arg || *end || res > 255) - return -1; - } - *id = res; - return 0; -} - -int get_rt_realms(__u32 *realms, char *arg) -{ - __u32 realm = 0; - char *p = strchr(arg, '/'); - - *realms = 0; - if (p) { - *p = 0; - if (rtnl_rtrealm_a2n(realms, arg)) { - *p = '/'; - return -1; - } - *realms <<= 16; - *p = '/'; - arg = p+1; - } - if (*arg && rtnl_rtrealm_a2n(&realm, arg)) - return -1; - *realms |= realm; - return 0; -} diff --git a/ip/rtmon.c b/ip/rtmon.c deleted file mode 100644 index 5ce7731..0000000 --- a/ip/rtmon.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * rtmon.c RTnetlink listener. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <net/if.h> -#include <netinet/in.h> -#include <string.h> - -#include "SNAPSHOT.h" - -#include "utils.h" -#include "libnetlink.h" - -int resolve_hosts = 0; -static int init_phase = 1; - -static void write_stamp(FILE *fp) -{ - char buf[128]; - struct nlmsghdr *n1 = (void*)buf; - struct timeval tv; - - n1->nlmsg_type = 15; - n1->nlmsg_flags = 0; - n1->nlmsg_seq = 0; - n1->nlmsg_pid = 0; - n1->nlmsg_len = NLMSG_LENGTH(4*2); - gettimeofday(&tv, NULL); - ((__u32*)NLMSG_DATA(n1))[0] = tv.tv_sec; - ((__u32*)NLMSG_DATA(n1))[1] = tv.tv_usec; - fwrite((void*)n1, 1, NLMSG_ALIGN(n1->nlmsg_len), fp); -} - -static int dump_msg(const struct sockaddr_nl *who, struct nlmsghdr *n, - void *arg) -{ - FILE *fp = (FILE*)arg; - if (!init_phase) - write_stamp(fp); - fwrite((void*)n, 1, NLMSG_ALIGN(n->nlmsg_len), fp); - fflush(fp); - return 0; -} - -void usage(void) -{ - fprintf(stderr, "Usage: rtmon file FILE [ all | LISTofOBJECTS]\n"); - fprintf(stderr, "LISTofOBJECTS := [ link ] [ address ] [ route ]\n"); - exit(-1); -} - -int -main(int argc, char **argv) -{ - FILE *fp; - struct rtnl_handle rth; - int family = AF_UNSPEC; - unsigned groups = ~0U; - int llink = 0; - int laddr = 0; - int lroute = 0; - char *file = NULL; - - while (argc > 1) { - if (matches(argv[1], "-family") == 0) { - argc--; - argv++; - if (argc <= 1) - usage(); - if (strcmp(argv[1], "inet") == 0) - family = AF_INET; - else if (strcmp(argv[1], "inet6") == 0) - family = AF_INET6; - else if (strcmp(argv[1], "link") == 0) - family = AF_INET6; - else if (strcmp(argv[1], "help") == 0) - usage(); - else { - fprintf(stderr, "Protocol ID \"%s\" is unknown, try \"rtmon help\".\n", argv[1]); - exit(-1); - } - } else if (strcmp(argv[1], "-4") == 0) { - family = AF_INET; - } else if (strcmp(argv[1], "-6") == 0) { - family = AF_INET6; - } else if (strcmp(argv[1], "-0") == 0) { - family = AF_PACKET; - } else if (matches(argv[1], "-Version") == 0) { - printf("rtmon utility, iproute2-ss%s\n", SNAPSHOT); - exit(0); - } else if (matches(argv[1], "file") == 0) { - argc--; - argv++; - if (argc <= 1) - usage(); - file = argv[1]; - } else if (matches(argv[1], "link") == 0) { - llink=1; - groups = 0; - } else if (matches(argv[1], "address") == 0) { - laddr=1; - groups = 0; - } else if (matches(argv[1], "route") == 0) { - lroute=1; - groups = 0; - } else if (strcmp(argv[1], "all") == 0) { - groups = ~0U; - } else if (matches(argv[1], "help") == 0) { - usage(); - } else { - fprintf(stderr, "Argument \"%s\" is unknown, try \"rtmon help\".\n", argv[1]); - exit(-1); - } - argc--; argv++; - } - - if (file == NULL) { - fprintf(stderr, "Not enough information: argument \"file\" is required\n"); - exit(-1); - } - if (llink) - groups |= RTMGRP_LINK; - if (laddr) { - if (!family || family == AF_INET) - groups |= RTMGRP_IPV4_IFADDR; - if (!family || family == AF_INET6) - groups |= RTMGRP_IPV6_IFADDR; - } - if (lroute) { - if (!family || family == AF_INET) - groups |= RTMGRP_IPV4_ROUTE; - if (!family || family == AF_INET6) - groups |= RTMGRP_IPV6_ROUTE; - } - - fp = fopen(file, "w"); - if (fp == NULL) { - perror("Cannot fopen"); - exit(-1); - } - - if (rtnl_open(&rth, groups) < 0) - exit(1); - - if (rtnl_wilddump_request(&rth, AF_UNSPEC, RTM_GETLINK) < 0) { - perror("Cannot send dump request"); - exit(1); - } - - write_stamp(fp); - - if (rtnl_dump_filter(&rth, dump_msg, fp, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - return 1; - } - - init_phase = 0; - - if (rtnl_listen(&rth, dump_msg, (void*)fp) < 0) - exit(2); - - exit(0); -} diff --git a/ip/rtpr b/ip/rtpr deleted file mode 100755 index c3629fd..0000000 --- a/ip/rtpr +++ /dev/null @@ -1,4 +0,0 @@ -#! /bin/bash - -exec tr "[\\\\]" "[ -]" diff --git a/ip/xfrm.h b/ip/xfrm.h deleted file mode 100644 index 4833b36..0000000 --- a/ip/xfrm.h +++ /dev/null @@ -1,143 +0,0 @@ -/* $USAGI: $ */ - -/* - * Copyright (C)2004 USAGI/WIDE Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -/* - * Authors: - * Masahide NAKAMURA @USAGI - */ - -#ifndef __XFRM_H__ -#define __XFRM_H__ 1 - -#include <stdio.h> -#include <sys/socket.h> -#include <linux/xfrm.h> - -#ifndef IPPROTO_SCTP -# define IPPROTO_SCTP 132 -#endif -#ifndef IPPPROTO_DCCP -# define IPPROTO_DCCP 33 -#endif - -#define XFRMS_RTA(x) ((struct rtattr*)(((char*)(x)) + NLMSG_ALIGN(sizeof(struct xfrm_usersa_info)))) -#define XFRMS_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct xfrm_usersa_info)) - -#define XFRMP_RTA(x) ((struct rtattr*)(((char*)(x)) + NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_info)))) -#define XFRMP_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct xfrm_userpoilcy_info)) - -#define XFRMSID_RTA(x) ((struct rtattr*)(((char*)(x)) + NLMSG_ALIGN(sizeof(struct xfrm_usersa_id)))) -#define XFRMSID_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct xfrm_usersa_id)) - -#define XFRMPID_RTA(x) ((struct rtattr*)(((char*)(x)) + NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_id)))) -#define XFRMPID_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct xfrm_userpoilcy_id)) - -#define XFRMACQ_RTA(x) ((struct rtattr*)(((char*)(x)) + NLMSG_ALIGN(sizeof(struct xfrm_user_acquire)))) -#define XFRMEXP_RTA(x) ((struct rtattr*)(((char*)(x)) + NLMSG_ALIGN(sizeof(struct xfrm_user_expire)))) -#define XFRMPEXP_RTA(x) ((struct rtattr*)(((char*)(x)) + NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire)))) - -#define XFRM_FLAG_PRINT(fp, flags, f, s) \ - do { \ - if (flags & f) { \ - flags &= ~f; \ - fprintf(fp, s "%s", (flags ? " " : "")); \ - } \ - } while(0) - -struct xfrm_buffer { - char *buf; - int size; - int offset; - - int nlmsg_count; - struct rtnl_handle *rth; -}; - -struct xfrm_filter { - int use; - - struct xfrm_usersa_info xsinfo; - __u8 id_src_mask; - __u8 id_dst_mask; - __u8 id_proto_mask; - __u32 id_spi_mask; - __u8 mode_mask; - __u32 reqid_mask; - __u8 state_flags_mask; - - struct xfrm_userpolicy_info xpinfo; - __u8 dir_mask; - __u8 sel_src_mask; - __u8 sel_dst_mask; - __u32 sel_dev_mask; - __u8 upspec_proto_mask; - __u16 upspec_sport_mask; - __u16 upspec_dport_mask; - __u32 index_mask; - __u8 action_mask; - __u32 priority_mask; -}; -#define XFRM_FILTER_MASK_FULL (~0) - -extern struct xfrm_filter filter; - -int xfrm_state_print(const struct sockaddr_nl *who, struct nlmsghdr *n, - void *arg); -int xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n, - void *arg); -int do_xfrm_state(int argc, char **argv); -int do_xfrm_policy(int argc, char **argv); -int do_xfrm_monitor(int argc, char **argv); - -int xfrm_addr_match(xfrm_address_t *x1, xfrm_address_t *x2, int bits); -int xfrm_xfrmproto_getbyname(char *name); -int xfrm_algotype_getbyname(char *name); -const char *strxf_xfrmproto(__u8 proto); -const char *strxf_algotype(int type); -const char *strxf_mask8(__u8 mask); -const char *strxf_mask32(__u32 mask); -const char *strxf_share(__u8 share); -const char *strxf_proto(__u8 proto); -void xfrm_id_info_print(xfrm_address_t *saddr, struct xfrm_id *id, - __u8 mode, __u32 reqid, __u16 family, int force_spi, - FILE *fp, const char *prefix, const char *title); -void xfrm_stats_print(struct xfrm_stats *s, FILE *fp, const char *prefix); -void xfrm_lifetime_print(struct xfrm_lifetime_cfg *cfg, - struct xfrm_lifetime_cur *cur, - FILE *fp, const char *prefix); -void xfrm_selector_print(struct xfrm_selector *sel, __u16 family, - FILE *fp, const char *prefix); -void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, - FILE *fp, const char *prefix); -void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo, - struct rtattr *tb[], FILE *fp, const char *prefix, - const char *title); -void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo, - struct rtattr *tb[], FILE *fp, const char *prefix, - const char *title); -int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family, - int loose, int *argcp, char ***argvp); -int xfrm_mode_parse(__u8 *mode, int *argcp, char ***argvp); -int xfrm_encap_type_parse(__u16 *type, int *argcp, char ***argvp); -int xfrm_reqid_parse(__u32 *reqid, int *argcp, char ***argvp); -int xfrm_selector_parse(struct xfrm_selector *sel, int *argcp, char ***argvp); -int xfrm_lifetime_cfg_parse(struct xfrm_lifetime_cfg *lft, - int *argcp, char ***argvp); - -#endif diff --git a/ip/xfrm_monitor.c b/ip/xfrm_monitor.c deleted file mode 100644 index 153621f..0000000 --- a/ip/xfrm_monitor.c +++ /dev/null @@ -1,218 +0,0 @@ -/* $USAGI: $ */ - -/* - * Copyright (C)2005 USAGI/WIDE Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -/* - * based on ipmonitor.c - */ -/* - * Authors: - * Masahide NAKAMURA @USAGI - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <linux/xfrm.h> -#include "utils.h" -#include "xfrm.h" -#include "ip_common.h" - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, "Usage: ip xfrm monitor [ all | LISTofOBJECTS ]\n"); - exit(-1); -} - -static int xfrm_acquire_print(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg) -{ - FILE *fp = (FILE*)arg; - struct xfrm_user_acquire *xacq = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr * tb[XFRMA_MAX+1]; - __u16 family; - - if (n->nlmsg_type != XFRM_MSG_ACQUIRE) { - fprintf(stderr, "Not an acquire: %08x %08x %08x\n", - n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); - return 0; - } - - len -= NLMSG_LENGTH(sizeof(*xacq)); - if (len < 0) { - fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); - return -1; - } - - parse_rtattr(tb, XFRMA_MAX, XFRMACQ_RTA(xacq), len); - - family = xacq->sel.family; - if (family == AF_UNSPEC) - family = xacq->policy.sel.family; - if (family == AF_UNSPEC) - family = preferred_family; - - fprintf(fp, "acquire "); - - fprintf(fp, "proto %s ", strxf_xfrmproto(xacq->id.proto)); - if (show_stats > 0 || xacq->id.spi) { - __u32 spi = ntohl(xacq->id.spi); - fprintf(fp, "spi 0x%08x", spi); - if (show_stats > 0) - fprintf(fp, "(%u)", spi); - fprintf(fp, " "); - } - fprintf(fp, "%s", _SL_); - - xfrm_selector_print(&xacq->sel, family, fp, " sel "); - - xfrm_policy_info_print(&xacq->policy, tb, fp, " ", " policy "); - - if (show_stats > 0) - fprintf(fp, " seq 0x%08u ", xacq->seq); - if (show_stats > 0) { - fprintf(fp, "%s-mask %s ", - strxf_algotype(XFRMA_ALG_CRYPT), - strxf_mask32(xacq->ealgos)); - fprintf(fp, "%s-mask %s ", - strxf_algotype(XFRMA_ALG_AUTH), - strxf_mask32(xacq->aalgos)); - fprintf(fp, "%s-mask %s", - strxf_algotype(XFRMA_ALG_COMP), - strxf_mask32(xacq->calgos)); - } - fprintf(fp, "%s", _SL_); - - if (oneline) - fprintf(fp, "\n"); - fflush(fp); - - return 0; -} - -static int xfrm_accept_msg(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg) -{ - FILE *fp = (FILE*)arg; - - if (timestamp) - print_timestamp(fp); - - if (n->nlmsg_type == XFRM_MSG_NEWSA || - n->nlmsg_type == XFRM_MSG_DELSA || - n->nlmsg_type == XFRM_MSG_UPDSA || - n->nlmsg_type == XFRM_MSG_EXPIRE) { - xfrm_state_print(who, n, arg); - return 0; - } - if (n->nlmsg_type == XFRM_MSG_NEWPOLICY || - n->nlmsg_type == XFRM_MSG_DELPOLICY || - n->nlmsg_type == XFRM_MSG_UPDPOLICY || - n->nlmsg_type == XFRM_MSG_POLEXPIRE) { - xfrm_policy_print(who, n, arg); - return 0; - } - - if (n->nlmsg_type == XFRM_MSG_ACQUIRE) { - xfrm_acquire_print(who, n, arg); - return 0; - } - if (n->nlmsg_type == XFRM_MSG_FLUSHSA) { - /* XXX: Todo: show proto in xfrm_usersa_flush */ - fprintf(fp, "Flushed state\n"); - return 0; - } - if (n->nlmsg_type == XFRM_MSG_FLUSHPOLICY) { - fprintf(fp, "Flushed policy\n"); - return 0; - } - if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP && - n->nlmsg_type != NLMSG_DONE) { - fprintf(fp, "Unknown message: %08d 0x%08x 0x%08x\n", - n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); - } - return 0; -} - -int do_xfrm_monitor(int argc, char **argv) -{ - struct rtnl_handle rth; - char *file = NULL; - unsigned groups = ~((unsigned)0); /* XXX */ - int lacquire=0; - int lexpire=0; - int lpolicy=0; - int lsa=0; - - while (argc > 0) { - if (matches(*argv, "file") == 0) { - NEXT_ARG(); - file = *argv; - } else if (matches(*argv, "acquire") == 0) { - lacquire=1; - groups = 0; - } else if (matches(*argv, "expire") == 0) { - lexpire=1; - groups = 0; - } else if (matches(*argv, "SA") == 0) { - lsa=1; - groups = 0; - } else if (matches(*argv, "policy") == 0) { - lpolicy=1; - groups = 0; - } else if (matches(*argv, "help") == 0) { - usage(); - } else { - fprintf(stderr, "Argument \"%s\" is unknown, try \"ip xfrm monitor help\".\n", *argv); - exit(-1); - } - argc--; argv++; - } - - if (lacquire) - groups |= XFRMGRP_ACQUIRE; - if (lexpire) - groups |= XFRMGRP_EXPIRE; - if (lsa) - groups |= XFRMGRP_SA; - if (lpolicy) - groups |= XFRMGRP_POLICY; - - if (file) { - FILE *fp; - fp = fopen(file, "r"); - if (fp == NULL) { - perror("Cannot fopen"); - exit(-1); - } - return rtnl_from_file(fp, xfrm_accept_msg, (void*)stdout); - } - - //ll_init_map(&rth); - - if (rtnl_open_byproto(&rth, groups, NETLINK_XFRM) < 0) - exit(1); - - if (rtnl_listen(&rth, xfrm_accept_msg, (void*)stdout) < 0) - exit(2); - - return 0; -} diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c deleted file mode 100644 index 433b513..0000000 --- a/ip/xfrm_policy.c +++ /dev/null @@ -1,738 +0,0 @@ -/* $USAGI: $ */ - -/* - * Copyright (C)2004 USAGI/WIDE Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -/* - * based on iproute.c - */ -/* - * Authors: - * Masahide NAKAMURA @USAGI - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netdb.h> -#include <linux/netlink.h> -#include <linux/xfrm.h> -#include "utils.h" -#include "xfrm.h" -#include "ip_common.h" - -//#define NLMSG_DELETEALL_BUF_SIZE (4096-512) -#define NLMSG_DELETEALL_BUF_SIZE 8192 - -/* - * Receiving buffer defines: - * nlmsg - * data = struct xfrm_userpolicy_info - * rtattr - * data = struct xfrm_user_tmpl[] - */ -#define NLMSG_BUF_SIZE 4096 -#define RTA_BUF_SIZE 2048 -#define XFRM_TMPLS_BUF_SIZE 1024 - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, "Usage: ip xfrm policy { add | update } dir DIR SELECTOR [ index INDEX ] \n"); - fprintf(stderr, " [ action ACTION ] [ priority PRIORITY ] [ LIMIT-LIST ] [ TMPL-LIST ]\n"); - fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ]\n"); - fprintf(stderr, "Usage: ip xfrm policy { deleteall | list } [ dir DIR ] [ SELECTOR ]\n"); - fprintf(stderr, " [ index INDEX ] [ action ACTION ] [ priority PRIORITY ]\n"); - fprintf(stderr, "Usage: ip xfrm policy flush\n"); - fprintf(stderr, "DIR := [ in | out | fwd ]\n"); - - fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ UPSPEC ] [ dev DEV ]\n"); - - fprintf(stderr, "UPSPEC := proto PROTO [ [ sport PORT ] [ dport PORT ] |\n"); - fprintf(stderr, " [ type NUMBER ] [ code NUMBER ] ]\n"); - - //fprintf(stderr, "DEV - device name(default=none)\n"); - - fprintf(stderr, "ACTION := [ allow | block ](default=allow)\n"); - - //fprintf(stderr, "PRIORITY - priority value(default=0)\n"); - - fprintf(stderr, "LIMIT-LIST := [ LIMIT-LIST ] | [ limit LIMIT ]\n"); - fprintf(stderr, "LIMIT := [ [time-soft|time-hard|time-use-soft|time-use-hard] SECONDS ] |\n"); - fprintf(stderr, " [ [byte-soft|byte-hard] SIZE ] | [ [packet-soft|packet-hard] NUMBER ]\n"); - - fprintf(stderr, "TMPL-LIST := [ TMPL-LIST ] | [ tmpl TMPL ]\n"); - fprintf(stderr, "TMPL := ID [ mode MODE ] [ reqid REQID ] [ level LEVEL ]\n"); - fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ]\n"); - - //fprintf(stderr, "XFRM_PROTO := [ esp | ah | comp ]\n"); - fprintf(stderr, "XFRM_PROTO := [ "); - fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP)); - fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_AH)); - fprintf(stderr, "%s", strxf_xfrmproto(IPPROTO_COMP)); - fprintf(stderr, " ]\n"); - - fprintf(stderr, "MODE := [ transport | tunnel ](default=transport)\n"); - //fprintf(stderr, "REQID - number(default=0)\n"); - fprintf(stderr, "LEVEL := [ required | use ](default=required)\n"); - - exit(-1); -} - -static int xfrm_policy_dir_parse(__u8 *dir, int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - - if (strcmp(*argv, "in") == 0) - *dir = XFRM_POLICY_IN; - else if (strcmp(*argv, "out") == 0) - *dir = XFRM_POLICY_OUT; - else if (strcmp(*argv, "fwd") == 0) - *dir = XFRM_POLICY_FWD; - else - invarg("\"DIR\" is invalid", *argv); - - *argcp = argc; - *argvp = argv; - - return 0; -} - -static int xfrm_tmpl_parse(struct xfrm_user_tmpl *tmpl, - int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - char *idp = NULL; - - while (1) { - if (strcmp(*argv, "mode") == 0) { - NEXT_ARG(); - xfrm_mode_parse(&tmpl->mode, &argc, &argv); - } else if (strcmp(*argv, "reqid") == 0) { - NEXT_ARG(); - xfrm_reqid_parse(&tmpl->reqid, &argc, &argv); - } else if (strcmp(*argv, "level") == 0) { - NEXT_ARG(); - - if (strcmp(*argv, "required") == 0) - tmpl->optional = 0; - else if (strcmp(*argv, "use") == 0) - tmpl->optional = 1; - else - invarg("\"LEVEL\" is invalid\n", *argv); - - } else { - if (idp) { - PREV_ARG(); /* back track */ - break; - } - idp = *argv; - xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family, - 0, &argc, &argv); - if (preferred_family == AF_UNSPEC) - preferred_family = tmpl->family; - } - - if (!NEXT_ARG_OK()) - break; - - NEXT_ARG(); - } - if (argc == *argcp) - missarg("TMPL"); - - *argcp = argc; - *argvp = argv; - - return 0; -} - -static int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv) -{ - struct rtnl_handle rth; - struct { - struct nlmsghdr n; - struct xfrm_userpolicy_info xpinfo; - char buf[RTA_BUF_SIZE]; - } req; - char *dirp = NULL; - char *selp = NULL; - char tmpls_buf[XFRM_TMPLS_BUF_SIZE]; - int tmpls_len = 0; - - memset(&req, 0, sizeof(req)); - memset(&tmpls_buf, 0, sizeof(tmpls_buf)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpinfo)); - req.n.nlmsg_flags = NLM_F_REQUEST|flags; - req.n.nlmsg_type = cmd; - req.xpinfo.sel.family = preferred_family; - - req.xpinfo.lft.soft_byte_limit = XFRM_INF; - req.xpinfo.lft.hard_byte_limit = XFRM_INF; - req.xpinfo.lft.soft_packet_limit = XFRM_INF; - req.xpinfo.lft.hard_packet_limit = XFRM_INF; - - while (argc > 0) { - if (strcmp(*argv, "dir") == 0) { - if (dirp) - duparg("dir", *argv); - dirp = *argv; - - NEXT_ARG(); - xfrm_policy_dir_parse(&req.xpinfo.dir, &argc, &argv); - - filter.dir_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "index") == 0) { - NEXT_ARG(); - if (get_u32(&req.xpinfo.index, *argv, 0)) - invarg("\"INDEX\" is invalid", *argv); - - filter.index_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "action") == 0) { - NEXT_ARG(); - if (strcmp(*argv, "allow") == 0) - req.xpinfo.action = XFRM_POLICY_ALLOW; - else if (strcmp(*argv, "block") == 0) - req.xpinfo.action = XFRM_POLICY_BLOCK; - else - invarg("\"action\" value is invalid\n", *argv); - - filter.action_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "priority") == 0) { - NEXT_ARG(); - if (get_u32(&req.xpinfo.priority, *argv, 0)) - invarg("\"PRIORITY\" is invalid", *argv); - - filter.priority_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "limit") == 0) { - NEXT_ARG(); - xfrm_lifetime_cfg_parse(&req.xpinfo.lft, &argc, &argv); - } else if (strcmp(*argv, "tmpl") == 0) { - struct xfrm_user_tmpl *tmpl; - - if (tmpls_len + sizeof(*tmpl) > sizeof(tmpls_buf)) { - fprintf(stderr, "Too many tmpls: buffer overflow\n"); - exit(1); - } - tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len); - - tmpl->family = preferred_family; - tmpl->aalgos = (~(__u32)0); - tmpl->ealgos = (~(__u32)0); - tmpl->calgos = (~(__u32)0); - - NEXT_ARG(); - xfrm_tmpl_parse(tmpl, &argc, &argv); - - tmpls_len += sizeof(*tmpl); - } else { - if (selp) - duparg("unknown", *argv); - selp = *argv; - - xfrm_selector_parse(&req.xpinfo.sel, &argc, &argv); - if (preferred_family == AF_UNSPEC) - preferred_family = req.xpinfo.sel.family; - } - - argc--; argv++; - } - - if (!dirp) { - fprintf(stderr, "Not enough information: \"DIR\" is required.\n"); - exit(1); - } - - if (tmpls_len > 0) { - addattr_l(&req.n, sizeof(req), XFRMA_TMPL, - (void *)tmpls_buf, tmpls_len); - } - - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - - if (req.xpinfo.sel.family == AF_UNSPEC) - req.xpinfo.sel.family = AF_INET; - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - exit(2); - - rtnl_close(&rth); - - return 0; -} - -static int xfrm_policy_filter_match(struct xfrm_userpolicy_info *xpinfo) -{ - if (!filter.use) - return 1; - - if ((xpinfo->dir^filter.xpinfo.dir)&filter.dir_mask) - return 0; - - if (filter.sel_src_mask) { - if (xfrm_addr_match(&xpinfo->sel.saddr, &filter.xpinfo.sel.saddr, - filter.sel_src_mask)) - return 0; - } - - if (filter.sel_dst_mask) { - if (xfrm_addr_match(&xpinfo->sel.daddr, &filter.xpinfo.sel.daddr, - filter.sel_dst_mask)) - return 0; - } - - if ((xpinfo->sel.ifindex^filter.xpinfo.sel.ifindex)&filter.sel_dev_mask) - return 0; - - if ((xpinfo->sel.proto^filter.xpinfo.sel.proto)&filter.upspec_proto_mask) - return 0; - - if (filter.upspec_sport_mask) { - if ((xpinfo->sel.sport^filter.xpinfo.sel.sport)&filter.upspec_sport_mask) - return 0; - } - - if (filter.upspec_dport_mask) { - if ((xpinfo->sel.dport^filter.xpinfo.sel.dport)&filter.upspec_dport_mask) - return 0; - } - - if ((xpinfo->index^filter.xpinfo.index)&filter.index_mask) - return 0; - - if ((xpinfo->action^filter.xpinfo.action)&filter.action_mask) - return 0; - - if ((xpinfo->priority^filter.xpinfo.priority)&filter.priority_mask) - return 0; - - return 1; -} - -int xfrm_policy_print(const struct sockaddr_nl *who, struct nlmsghdr *n, - void *arg) -{ - struct rtattr * tb[XFRMA_MAX+1]; - struct rtattr * rta; - struct xfrm_userpolicy_info *xpinfo = NULL; - struct xfrm_user_polexpire *xpexp = NULL; - struct xfrm_userpolicy_id *xpid = NULL; - FILE *fp = (FILE*)arg; - int len = n->nlmsg_len; - - if (n->nlmsg_type != XFRM_MSG_NEWPOLICY && - n->nlmsg_type != XFRM_MSG_DELPOLICY && - n->nlmsg_type != XFRM_MSG_UPDPOLICY && - n->nlmsg_type != XFRM_MSG_POLEXPIRE) { - fprintf(stderr, "Not a policy: %08x %08x %08x\n", - n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); - return 0; - } - - if (n->nlmsg_type == XFRM_MSG_DELPOLICY) { - xpid = NLMSG_DATA(n); - len -= NLMSG_LENGTH(sizeof(*xpid)); - } else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) { - xpexp = NLMSG_DATA(n); - xpinfo = &xpexp->pol; - len -= NLMSG_LENGTH(sizeof(*xpexp)); - } else { - xpexp = NULL; - xpinfo = NLMSG_DATA(n); - len -= NLMSG_LENGTH(sizeof(*xpinfo)); - } - - if (len < 0) { - fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); - return -1; - } - - if (xpinfo && !xfrm_policy_filter_match(xpinfo)) - return 0; - - if (n->nlmsg_type == XFRM_MSG_DELPOLICY) - fprintf(fp, "Deleted "); - else if (n->nlmsg_type == XFRM_MSG_UPDPOLICY) - fprintf(fp, "Updated "); - else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) - fprintf(fp, "Expired "); - - if (n->nlmsg_type == XFRM_MSG_DELPOLICY) - rta = XFRMPID_RTA(xpid); - else if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) - rta = XFRMPEXP_RTA(xpexp); - else - rta = XFRMP_RTA(xpinfo); - - parse_rtattr(tb, XFRMA_MAX, rta, len); - - if (n->nlmsg_type == XFRM_MSG_DELPOLICY) { - //xfrm_policy_id_print(); - if (!tb[XFRMA_POLICY]) { - fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: no XFRMA_POLICY\n"); - return -1; - } - if (RTA_PAYLOAD(tb[XFRMA_POLICY]) < sizeof(*xpinfo)) { - fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: too short XFRMA_POLICY len\n"); - return -1; - } - xpinfo = (struct xfrm_userpolicy_info *)RTA_DATA(tb[XFRMA_POLICY]); - } - - xfrm_policy_info_print(xpinfo, tb, fp, NULL, NULL); - - if (n->nlmsg_type == XFRM_MSG_POLEXPIRE) { - fprintf(fp, "\t"); - fprintf(fp, "hard %u", xpexp->hard); - fprintf(fp, "%s", _SL_); - } - - if (oneline) - fprintf(fp, "\n"); - fflush(fp); - - return 0; -} - -static int xfrm_policy_get_or_delete(int argc, char **argv, int delete, - void *res_nlbuf) -{ - struct rtnl_handle rth; - struct { - struct nlmsghdr n; - struct xfrm_userpolicy_id xpid; - } req; - char *dirp = NULL; - char *selp = NULL; - char *indexp = NULL; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid)); - req.n.nlmsg_flags = NLM_F_REQUEST; - req.n.nlmsg_type = delete ? XFRM_MSG_DELPOLICY : XFRM_MSG_GETPOLICY; - - while (argc > 0) { - if (strcmp(*argv, "dir") == 0) { - if (dirp) - duparg("dir", *argv); - dirp = *argv; - - NEXT_ARG(); - xfrm_policy_dir_parse(&req.xpid.dir, &argc, &argv); - - } else if (strcmp(*argv, "index") == 0) { - if (indexp) - duparg("index", *argv); - indexp = *argv; - - NEXT_ARG(); - if (get_u32(&req.xpid.index, *argv, 0)) - invarg("\"INDEX\" is invalid", *argv); - - } else { - if (selp) - invarg("unknown", *argv); - selp = *argv; - - xfrm_selector_parse(&req.xpid.sel, &argc, &argv); - if (preferred_family == AF_UNSPEC) - preferred_family = req.xpid.sel.family; - - } - - argc--; argv++; - } - - if (!dirp) { - fprintf(stderr, "Not enough information: \"DIR\" is required.\n"); - exit(1); - } - if (!selp && !indexp) { - fprintf(stderr, "Not enough information: either \"SELECTOR\" or \"INDEX\" is required.\n"); - exit(1); - } - if (selp && indexp) - duparg2("SELECTOR", "INDEX"); - - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - - if (req.xpid.sel.family == AF_UNSPEC) - req.xpid.sel.family = AF_INET; - - if (rtnl_talk(&rth, &req.n, 0, 0, res_nlbuf, NULL, NULL) < 0) - exit(2); - - rtnl_close(&rth); - - return 0; -} - -static int xfrm_policy_delete(int argc, char **argv) -{ - return xfrm_policy_get_or_delete(argc, argv, 1, NULL); -} - -static int xfrm_policy_get(int argc, char **argv) -{ - char buf[NLMSG_BUF_SIZE]; - struct nlmsghdr *n = (struct nlmsghdr *)buf; - - memset(buf, 0, sizeof(buf)); - - xfrm_policy_get_or_delete(argc, argv, 0, n); - - if (xfrm_policy_print(NULL, n, (void*)stdout) < 0) { - fprintf(stderr, "An error :-)\n"); - exit(1); - } - - return 0; -} - -/* - * With an existing policy of nlmsg, make new nlmsg for deleting the policy - * and store it to buffer. - */ -static int xfrm_policy_keep(const struct sockaddr_nl *who, - struct nlmsghdr *n, - void *arg) -{ - struct xfrm_buffer *xb = (struct xfrm_buffer *)arg; - struct rtnl_handle *rth = xb->rth; - struct xfrm_userpolicy_info *xpinfo = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct nlmsghdr *new_n; - struct xfrm_userpolicy_id *xpid; - - if (n->nlmsg_type != XFRM_MSG_NEWPOLICY) { - fprintf(stderr, "Not a policy: %08x %08x %08x\n", - n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); - return 0; - } - - len -= NLMSG_LENGTH(sizeof(*xpinfo)); - if (len < 0) { - fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); - return -1; - } - - if (!xfrm_policy_filter_match(xpinfo)) - return 0; - - if (xb->offset > xb->size) { - fprintf(stderr, "Policy buffer overflow\n"); - return -1; - } - - new_n = (struct nlmsghdr *)(xb->buf + xb->offset); - new_n->nlmsg_len = NLMSG_LENGTH(sizeof(*xpid)); - new_n->nlmsg_flags = NLM_F_REQUEST; - new_n->nlmsg_type = XFRM_MSG_DELPOLICY; - new_n->nlmsg_seq = ++rth->seq; - - xpid = NLMSG_DATA(new_n); - memcpy(&xpid->sel, &xpinfo->sel, sizeof(xpid->sel)); - xpid->dir = xpinfo->dir; - xpid->index = xpinfo->index; - - xb->offset += new_n->nlmsg_len; - xb->nlmsg_count ++; - - return 0; -} - -static int xfrm_policy_list_or_deleteall(int argc, char **argv, int deleteall) -{ - char *selp = NULL; - struct rtnl_handle rth; - - if (argc > 0) - filter.use = 1; - filter.xpinfo.sel.family = preferred_family; - - while (argc > 0) { - if (strcmp(*argv, "dir") == 0) { - NEXT_ARG(); - xfrm_policy_dir_parse(&filter.xpinfo.dir, &argc, &argv); - - filter.dir_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "index") == 0) { - NEXT_ARG(); - if (get_u32(&filter.xpinfo.index, *argv, 0)) - invarg("\"INDEX\" is invalid", *argv); - - filter.index_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "action") == 0) { - NEXT_ARG(); - if (strcmp(*argv, "allow") == 0) - filter.xpinfo.action = XFRM_POLICY_ALLOW; - else if (strcmp(*argv, "block") == 0) - filter.xpinfo.action = XFRM_POLICY_BLOCK; - else - invarg("\"ACTION\" is invalid\n", *argv); - - filter.action_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "priority") == 0) { - NEXT_ARG(); - if (get_u32(&filter.xpinfo.priority, *argv, 0)) - invarg("\"PRIORITY\" is invalid", *argv); - - filter.priority_mask = XFRM_FILTER_MASK_FULL; - - } else { - if (selp) - invarg("unknown", *argv); - selp = *argv; - - xfrm_selector_parse(&filter.xpinfo.sel, &argc, &argv); - if (preferred_family == AF_UNSPEC) - preferred_family = filter.xpinfo.sel.family; - - } - - argc--; argv++; - } - - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - - if (deleteall) { - struct xfrm_buffer xb; - char buf[NLMSG_DELETEALL_BUF_SIZE]; - int i; - - xb.buf = buf; - xb.size = sizeof(buf); - xb.rth = &rth; - - for (i = 0; ; i++) { - xb.offset = 0; - xb.nlmsg_count = 0; - - if (show_stats > 1) - fprintf(stderr, "Delete-all round = %d\n", i); - - if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETPOLICY) < 0) { - perror("Cannot send dump request"); - exit(1); - } - - if (rtnl_dump_filter(&rth, xfrm_policy_keep, &xb, NULL, NULL) < 0) { - fprintf(stderr, "Delete-all terminated\n"); - exit(1); - } - if (xb.nlmsg_count == 0) { - if (show_stats > 1) - fprintf(stderr, "Delete-all completed\n"); - break; - } - - if (rtnl_send(&rth, xb.buf, xb.offset) < 0) { - perror("Failed to send delete-all request\n"); - exit(1); - } - if (show_stats > 1) - fprintf(stderr, "Delete-all nlmsg count = %d\n", xb.nlmsg_count); - - xb.offset = 0; - xb.nlmsg_count = 0; - } - } else { - if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETPOLICY) < 0) { - perror("Cannot send dump request"); - exit(1); - } - - if (rtnl_dump_filter(&rth, xfrm_policy_print, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - exit(1); - } - } - - rtnl_close(&rth); - - exit(0); -} - -static int xfrm_policy_flush(void) -{ - struct rtnl_handle rth; - struct { - struct nlmsghdr n; - } req; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(0); /* nlmsg data is nothing */ - req.n.nlmsg_flags = NLM_F_REQUEST; - req.n.nlmsg_type = XFRM_MSG_FLUSHPOLICY; - - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - - if (show_stats > 1) - fprintf(stderr, "Flush policy\n"); - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - exit(2); - - rtnl_close(&rth); - - return 0; -} - -int do_xfrm_policy(int argc, char **argv) -{ - if (argc < 1) - return xfrm_policy_list_or_deleteall(0, NULL, 0); - - if (matches(*argv, "add") == 0) - return xfrm_policy_modify(XFRM_MSG_NEWPOLICY, 0, - argc-1, argv+1); - if (matches(*argv, "update") == 0) - return xfrm_policy_modify(XFRM_MSG_UPDPOLICY, 0, - argc-1, argv+1); - if (matches(*argv, "delete") == 0) - return xfrm_policy_delete(argc-1, argv+1); - if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0) - return xfrm_policy_list_or_deleteall(argc-1, argv+1, 1); - if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 - || matches(*argv, "lst") == 0) - return xfrm_policy_list_or_deleteall(argc-1, argv+1, 0); - if (matches(*argv, "get") == 0) - return xfrm_policy_get(argc-1, argv+1); - if (matches(*argv, "flush") == 0) - return xfrm_policy_flush(); - if (matches(*argv, "help") == 0) - usage(); - fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm policy help\".\n", *argv); - exit(-1); -} diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c deleted file mode 100644 index 3eefaff..0000000 --- a/ip/xfrm_state.c +++ /dev/null @@ -1,950 +0,0 @@ -/* $USAGI: $ */ - -/* - * Copyright (C)2004 USAGI/WIDE Project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -/* - * based on iproute.c - */ -/* - * Authors: - * Masahide NAKAMURA @USAGI - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netdb.h> -#include <linux/xfrm.h> -#include "utils.h" -#include "xfrm.h" -#include "ip_common.h" - -//#define NLMSG_DELETEALL_BUF_SIZE (4096-512) -#define NLMSG_DELETEALL_BUF_SIZE 8192 - -/* - * Receiving buffer defines: - * nlmsg - * data = struct xfrm_usersa_info - * rtattr - * rtattr - * ... (max count of rtattr is XFRM_MAX+1 - * - * each rtattr data = struct xfrm_algo(dynamic size) or xfrm_address_t - */ -#define NLMSG_BUF_SIZE 4096 -#define RTA_BUF_SIZE 2048 -#define XFRM_ALGO_KEY_BUF_SIZE 512 - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, "Usage: ip xfrm state { add | update } ID [ ALGO-LIST ] [ mode MODE ]\n"); - fprintf(stderr, " [ reqid REQID ] [ seq SEQ ] [ replay-window SIZE ] [ flag FLAG-LIST ]\n"); - fprintf(stderr, " [ encap ENCAP ] [ sel SELECTOR ] [ LIMIT-LIST ]\n"); - fprintf(stderr, "Usage: ip xfrm state allocspi ID [ mode MODE ] [ reqid REQID ] [ seq SEQ ]\n"); - fprintf(stderr, " [ min SPI max SPI ]\n"); - fprintf(stderr, "Usage: ip xfrm state { delete | get } ID\n"); - fprintf(stderr, "Usage: ip xfrm state { deleteall | list } [ ID ] [ mode MODE ] [ reqid REQID ]\n"); - fprintf(stderr, " [ flag FLAG_LIST ]\n"); - fprintf(stderr, "Usage: ip xfrm state flush [ proto XFRM_PROTO ]\n"); - - fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ]\n"); - //fprintf(stderr, "XFRM_PROTO := [ esp | ah | comp ]\n"); - fprintf(stderr, "XFRM_PROTO := [ "); - fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP)); - fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_AH)); - fprintf(stderr, "%s ", strxf_xfrmproto(IPPROTO_COMP)); - fprintf(stderr, "]\n"); - - //fprintf(stderr, "SPI - security parameter index(default=0)\n"); - - fprintf(stderr, "MODE := [ transport | tunnel ](default=transport)\n"); - //fprintf(stderr, "REQID - number(default=0)\n"); - - fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n"); - fprintf(stderr, "FLAG := [ noecn | decap-dscp ]\n"); - - fprintf(stderr, "ENCAP := ENCAP-TYPE SPORT DPORT OADDR\n"); - fprintf(stderr, "ENCAP-TYPE := espinudp | espinudp-nonike\n"); - - fprintf(stderr, "ALGO-LIST := [ ALGO-LIST ] | [ ALGO ]\n"); - fprintf(stderr, "ALGO := ALGO_TYPE ALGO_NAME ALGO_KEY\n"); - fprintf(stderr, "ALGO_TYPE := [ "); - fprintf(stderr, "%s | ", strxf_algotype(XFRMA_ALG_CRYPT)); - fprintf(stderr, "%s | ", strxf_algotype(XFRMA_ALG_AUTH)); - fprintf(stderr, "%s ", strxf_algotype(XFRMA_ALG_COMP)); - fprintf(stderr, "]\n"); - - //fprintf(stderr, "ALGO_NAME - algorithm name\n"); - //fprintf(stderr, "ALGO_KEY - algorithm key\n"); - - fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ UPSPEC ] [ dev DEV ]\n"); - - fprintf(stderr, "UPSPEC := proto PROTO [ [ sport PORT ] [ dport PORT ] |\n"); - fprintf(stderr, " [ type NUMBER ] [ code NUMBER ] ]\n"); - - - //fprintf(stderr, "DEV - device name(default=none)\n"); - fprintf(stderr, "LIMIT-LIST := [ LIMIT-LIST ] | [ limit LIMIT ]\n"); - fprintf(stderr, "LIMIT := [ [time-soft|time-hard|time-use-soft|time-use-hard] SECONDS ] |\n"); - fprintf(stderr, " [ [byte-soft|byte-hard] SIZE ] | [ [packet-soft|packet-hard] COUNT ]\n"); - exit(-1); -} - -static int xfrm_algo_parse(struct xfrm_algo *alg, enum xfrm_attr_type_t type, - char *name, char *key, int max) -{ - int len; - int slen = strlen(key); - -#if 0 - /* XXX: verifying both name and key is required! */ - fprintf(stderr, "warning: ALGONAME/ALGOKEY will send to kernel promiscuously!(verifying them isn't implemented yet)\n"); -#endif - - strncpy(alg->alg_name, name, sizeof(alg->alg_name)); - - if (slen > 2 && strncmp(key, "0x", 2) == 0) { - /* split two chars "0x" from the top */ - char *p = key + 2; - int plen = slen - 2; - int i; - int j; - - /* Converting hexadecimal numbered string into real key; - * Convert each two chars into one char(value). If number - * of the length is odd, add zero on the top for rounding. - */ - - /* calculate length of the converted values(real key) */ - len = (plen + 1) / 2; - if (len > max) - invarg("\"ALGOKEY\" makes buffer overflow\n", key); - - for (i = - (plen % 2), j = 0; j < len; i += 2, j++) { - char vbuf[3]; - __u8 val; - - vbuf[0] = i >= 0 ? p[i] : '0'; - vbuf[1] = p[i + 1]; - vbuf[2] = '\0'; - - if (get_u8(&val, vbuf, 16)) - invarg("\"ALGOKEY\" is invalid", key); - - alg->alg_key[j] = val; - } - } else { - len = slen; - if (len > 0) { - if (len > max) - invarg("\"ALGOKEY\" makes buffer overflow\n", key); - - strncpy(alg->alg_key, key, len); - } - } - - alg->alg_key_len = len * 8; - - return 0; -} - -static int xfrm_seq_parse(__u32 *seq, int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - - if (get_u32(seq, *argv, 0)) - invarg("\"SEQ\" is invalid", *argv); - - *seq = htonl(*seq); - - *argcp = argc; - *argvp = argv; - - return 0; -} - -static int xfrm_state_flag_parse(__u8 *flags, int *argcp, char ***argvp) -{ - int argc = *argcp; - char **argv = *argvp; - int len = strlen(*argv); - - if (len > 2 && strncmp(*argv, "0x", 2) == 0) { - __u8 val = 0; - - if (get_u8(&val, *argv, 16)) - invarg("\"FLAG\" is invalid", *argv); - *flags = val; - } else { - while (1) { - if (strcmp(*argv, "noecn") == 0) - *flags |= XFRM_STATE_NOECN; - else if (strcmp(*argv, "decap-dscp") == 0) - *flags |= XFRM_STATE_DECAP_DSCP; - else { - PREV_ARG(); /* back track */ - break; - } - - if (!NEXT_ARG_OK()) - break; - NEXT_ARG(); - } - } - - filter.state_flags_mask = XFRM_FILTER_MASK_FULL; - - *argcp = argc; - *argvp = argv; - - return 0; -} - -static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv) -{ - struct rtnl_handle rth; - struct { - struct nlmsghdr n; - struct xfrm_usersa_info xsinfo; - char buf[RTA_BUF_SIZE]; - } req; - char *idp = NULL; - char *ealgop = NULL; - char *aalgop = NULL; - char *calgop = NULL; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsinfo)); - req.n.nlmsg_flags = NLM_F_REQUEST|flags; - req.n.nlmsg_type = cmd; - req.xsinfo.family = preferred_family; - - req.xsinfo.lft.soft_byte_limit = XFRM_INF; - req.xsinfo.lft.hard_byte_limit = XFRM_INF; - req.xsinfo.lft.soft_packet_limit = XFRM_INF; - req.xsinfo.lft.hard_packet_limit = XFRM_INF; - - while (argc > 0) { - if (strcmp(*argv, "mode") == 0) { - NEXT_ARG(); - xfrm_mode_parse(&req.xsinfo.mode, &argc, &argv); - } else if (strcmp(*argv, "reqid") == 0) { - NEXT_ARG(); - xfrm_reqid_parse(&req.xsinfo.reqid, &argc, &argv); - } else if (strcmp(*argv, "seq") == 0) { - NEXT_ARG(); - xfrm_seq_parse(&req.xsinfo.seq, &argc, &argv); - } else if (strcmp(*argv, "replay-window") == 0) { - NEXT_ARG(); - if (get_u8(&req.xsinfo.replay_window, *argv, 0)) - invarg("\"replay-window\" value is invalid", *argv); - } else if (strcmp(*argv, "flag") == 0) { - NEXT_ARG(); - xfrm_state_flag_parse(&req.xsinfo.flags, &argc, &argv); - } else if (strcmp(*argv, "sel") == 0) { - NEXT_ARG(); - xfrm_selector_parse(&req.xsinfo.sel, &argc, &argv); - } else if (strcmp(*argv, "limit") == 0) { - NEXT_ARG(); - xfrm_lifetime_cfg_parse(&req.xsinfo.lft, &argc, &argv); - } else if (strcmp(*argv, "encap") == 0) { - struct xfrm_encap_tmpl encap; - inet_prefix oa; - NEXT_ARG(); - xfrm_encap_type_parse(&encap.encap_type, &argc, &argv); - NEXT_ARG(); - if (get_u16(&encap.encap_sport, *argv, 0)) - invarg("\"encap\" sport value is invalid", *argv); - encap.encap_sport = htons(encap.encap_sport); - NEXT_ARG(); - if (get_u16(&encap.encap_dport, *argv, 0)) - invarg("\"encap\" dport value is invalid", *argv); - encap.encap_dport = htons(encap.encap_dport); - NEXT_ARG(); - get_addr(&oa, *argv, AF_UNSPEC); - memcpy(&encap.encap_oa, &oa.data, sizeof(encap.encap_oa)); - addattr_l(&req.n, sizeof(req.buf), XFRMA_ENCAP, - (void *)&encap, sizeof(encap)); - } else { - /* try to assume ALGO */ - int type = xfrm_algotype_getbyname(*argv); - switch (type) { - case XFRMA_ALG_CRYPT: - case XFRMA_ALG_AUTH: - case XFRMA_ALG_COMP: - { - /* ALGO */ - struct { - struct xfrm_algo alg; - char buf[XFRM_ALGO_KEY_BUF_SIZE]; - } alg; - int len; - char *name; - char *key; - - switch (type) { - case XFRMA_ALG_CRYPT: - if (ealgop) - duparg("ALGOTYPE", *argv); - ealgop = *argv; - break; - case XFRMA_ALG_AUTH: - if (aalgop) - duparg("ALGOTYPE", *argv); - aalgop = *argv; - break; - case XFRMA_ALG_COMP: - if (calgop) - duparg("ALGOTYPE", *argv); - calgop = *argv; - break; - default: - /* not reached */ - invarg("\"ALGOTYPE\" is invalid\n", *argv); - } - - if (!NEXT_ARG_OK()) - missarg("ALGONAME"); - NEXT_ARG(); - name = *argv; - - if (!NEXT_ARG_OK()) - missarg("ALGOKEY"); - NEXT_ARG(); - key = *argv; - - memset(&alg, 0, sizeof(alg)); - - xfrm_algo_parse((void *)&alg, type, name, key, - sizeof(alg.buf)); - len = sizeof(struct xfrm_algo) + alg.alg.alg_key_len; - - addattr_l(&req.n, sizeof(req.buf), type, - (void *)&alg, len); - break; - } - default: - /* try to assume ID */ - if (idp) - invarg("unknown", *argv); - idp = *argv; - - /* ID */ - xfrm_id_parse(&req.xsinfo.saddr, &req.xsinfo.id, - &req.xsinfo.family, 0, &argc, &argv); - if (preferred_family == AF_UNSPEC) - preferred_family = req.xsinfo.family; - } - } - argc--; argv++; - } - - if (!idp) { - fprintf(stderr, "Not enough information: \"ID\" is required\n"); - exit(1); - } - - if (ealgop || aalgop || calgop) { - if (req.xsinfo.id.proto != IPPROTO_ESP && - req.xsinfo.id.proto != IPPROTO_AH && - req.xsinfo.id.proto != IPPROTO_COMP) { - fprintf(stderr, "\"ALGO\" is invalid with proto=%s\n", strxf_xfrmproto(req.xsinfo.id.proto)); - exit(1); - } - } else { - if (req.xsinfo.id.proto == IPPROTO_ESP || - req.xsinfo.id.proto == IPPROTO_AH || - req.xsinfo.id.proto == IPPROTO_COMP) { - fprintf(stderr, "\"ALGO\" is required with proto=%s\n", strxf_xfrmproto(req.xsinfo.id.proto)); - exit (1); - } - } - - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - - if (req.xsinfo.family == AF_UNSPEC) - req.xsinfo.family = AF_INET; - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - exit(2); - - rtnl_close(&rth); - - return 0; -} - -static int xfrm_state_allocspi(int argc, char **argv) -{ - struct rtnl_handle rth; - struct { - struct nlmsghdr n; - struct xfrm_userspi_info xspi; - char buf[RTA_BUF_SIZE]; - } req; - char *idp = NULL; - char *minp = NULL; - char *maxp = NULL; - char res_buf[NLMSG_BUF_SIZE]; - struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf; - - memset(res_buf, 0, sizeof(res_buf)); - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xspi)); - req.n.nlmsg_flags = NLM_F_REQUEST; - req.n.nlmsg_type = XFRM_MSG_ALLOCSPI; - req.xspi.info.family = preferred_family; - -#if 0 - req.xsinfo.lft.soft_byte_limit = XFRM_INF; - req.xsinfo.lft.hard_byte_limit = XFRM_INF; - req.xsinfo.lft.soft_packet_limit = XFRM_INF; - req.xsinfo.lft.hard_packet_limit = XFRM_INF; -#endif - - while (argc > 0) { - if (strcmp(*argv, "mode") == 0) { - NEXT_ARG(); - xfrm_mode_parse(&req.xspi.info.mode, &argc, &argv); - } else if (strcmp(*argv, "reqid") == 0) { - NEXT_ARG(); - xfrm_reqid_parse(&req.xspi.info.reqid, &argc, &argv); - } else if (strcmp(*argv, "seq") == 0) { - NEXT_ARG(); - xfrm_seq_parse(&req.xspi.info.seq, &argc, &argv); - } else if (strcmp(*argv, "min") == 0) { - if (minp) - duparg("min", *argv); - minp = *argv; - - NEXT_ARG(); - - if (get_u32(&req.xspi.min, *argv, 0)) - invarg("\"min\" value is invalid", *argv); - } else if (strcmp(*argv, "max") == 0) { - if (maxp) - duparg("max", *argv); - maxp = *argv; - - NEXT_ARG(); - - if (get_u32(&req.xspi.max, *argv, 0)) - invarg("\"max\" value is invalid", *argv); - } else { - /* try to assume ID */ - if (idp) - invarg("unknown", *argv); - idp = *argv; - - /* ID */ - xfrm_id_parse(&req.xspi.info.saddr, &req.xspi.info.id, - &req.xspi.info.family, 0, &argc, &argv); - if (req.xspi.info.id.spi) { - fprintf(stderr, "\"SPI\" must be zero\n"); - exit(1); - } - if (preferred_family == AF_UNSPEC) - preferred_family = req.xspi.info.family; - } - argc--; argv++; - } - - if (!idp) { - fprintf(stderr, "Not enough information: \"ID\" is required\n"); - exit(1); - } - - if (minp) { - if (!maxp) { - fprintf(stderr, "\"max\" is missing\n"); - exit(1); - } - if (req.xspi.min > req.xspi.max) { - fprintf(stderr, "\"min\" valie is larger than \"max\" one\n"); - exit(1); - } - } else { - if (maxp) { - fprintf(stderr, "\"min\" is missing\n"); - exit(1); - } - - /* XXX: Default value defined in PF_KEY; - * See kernel's net/key/af_key.c(pfkey_getspi). - */ - req.xspi.min = 0x100; - req.xspi.max = 0x0fffffff; - - /* XXX: IPCOMP spi is 16-bits; - * See kernel's net/xfrm/xfrm_user(verify_userspi_info). - */ - if (req.xspi.info.id.proto == IPPROTO_COMP) - req.xspi.max = 0xffff; - } - - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - - if (req.xspi.info.family == AF_UNSPEC) - req.xspi.info.family = AF_INET; - - - if (rtnl_talk(&rth, &req.n, 0, 0, res_n, NULL, NULL) < 0) - exit(2); - - if (xfrm_state_print(NULL, res_n, (void*)stdout) < 0) { - fprintf(stderr, "An error :-)\n"); - exit(1); - } - - rtnl_close(&rth); - - return 0; -} - -static int xfrm_state_filter_match(struct xfrm_usersa_info *xsinfo) -{ - if (!filter.use) - return 1; - - if (filter.id_src_mask) - if (xfrm_addr_match(&xsinfo->saddr, &filter.xsinfo.saddr, - filter.id_src_mask)) - return 0; - if (filter.id_dst_mask) - if (xfrm_addr_match(&xsinfo->id.daddr, &filter.xsinfo.id.daddr, - filter.id_dst_mask)) - return 0; - if ((xsinfo->id.proto^filter.xsinfo.id.proto)&filter.id_proto_mask) - return 0; - if ((xsinfo->id.spi^filter.xsinfo.id.spi)&filter.id_spi_mask) - return 0; - if ((xsinfo->mode^filter.xsinfo.mode)&filter.mode_mask) - return 0; - if ((xsinfo->reqid^filter.xsinfo.reqid)&filter.reqid_mask) - return 0; - if (filter.state_flags_mask) - if ((xsinfo->flags & filter.xsinfo.flags) == 0) - return 0; - - return 1; -} - -int xfrm_state_print(const struct sockaddr_nl *who, struct nlmsghdr *n, - void *arg) -{ - FILE *fp = (FILE*)arg; - struct rtattr * tb[XFRMA_MAX+1]; - struct rtattr * rta; - struct xfrm_usersa_info *xsinfo = NULL; - struct xfrm_user_expire *xexp = NULL; - struct xfrm_usersa_id *xsid = NULL; - int len = n->nlmsg_len; - - if (n->nlmsg_type != XFRM_MSG_NEWSA && - n->nlmsg_type != XFRM_MSG_DELSA && - n->nlmsg_type != XFRM_MSG_UPDSA && - n->nlmsg_type != XFRM_MSG_EXPIRE) { - fprintf(stderr, "Not a state: %08x %08x %08x\n", - n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); - return 0; - } - - if (n->nlmsg_type == XFRM_MSG_DELSA) { - /* Dont blame me for this .. Herbert made me do it */ - xsid = NLMSG_DATA(n); - len -= NLMSG_LENGTH(sizeof(*xsid)); - } else if (n->nlmsg_type == XFRM_MSG_EXPIRE) { - xexp = NLMSG_DATA(n); - xsinfo = &xexp->state; - len -= NLMSG_LENGTH(sizeof(*xexp)); - } else { - xexp = NULL; - xsinfo = NLMSG_DATA(n); - len -= NLMSG_LENGTH(sizeof(*xsinfo)); - } - - if (len < 0) { - fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); - return -1; - } - - if (xsinfo && !xfrm_state_filter_match(xsinfo)) - return 0; - - if (n->nlmsg_type == XFRM_MSG_DELSA) - fprintf(fp, "Deleted "); - else if (n->nlmsg_type == XFRM_MSG_UPDSA) - fprintf(fp, "Updated "); - else if (n->nlmsg_type == XFRM_MSG_EXPIRE) - fprintf(fp, "Expired "); - - if (n->nlmsg_type == XFRM_MSG_DELSA) - rta = XFRMSID_RTA(xsid); - else if (n->nlmsg_type == XFRM_MSG_EXPIRE) - rta = XFRMEXP_RTA(xexp); - else - rta = XFRMS_RTA(xsinfo); - - parse_rtattr(tb, XFRMA_MAX, rta, len); - - if (n->nlmsg_type == XFRM_MSG_DELSA) { - //xfrm_policy_id_print(); - - if (!tb[XFRMA_SA]) { - fprintf(stderr, "Buggy XFRM_MSG_DELSA: no XFRMA_SA\n"); - return -1; - } - if (RTA_PAYLOAD(tb[XFRMA_SA]) < sizeof(*xsinfo)) { - fprintf(stderr, "Buggy XFRM_MSG_DELPOLICY: too short XFRMA_POLICY len\n"); - return -1; - } - xsinfo = (struct xfrm_usersa_info *)RTA_DATA(tb[XFRMA_SA]); - } - - xfrm_state_info_print(xsinfo, tb, fp, NULL, NULL); - - if (n->nlmsg_type == XFRM_MSG_EXPIRE) { - fprintf(fp, "\t"); - fprintf(fp, "hard %u", xexp->hard); - fprintf(fp, "%s", _SL_); - } - - if (oneline) - fprintf(fp, "\n"); - fflush(fp); - - return 0; -} - -static int xfrm_state_get_or_delete(int argc, char **argv, int delete) -{ - struct rtnl_handle rth; - struct { - struct nlmsghdr n; - struct xfrm_usersa_id xsid; - } req; - struct xfrm_id id; - char *idp = NULL; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsid)); - req.n.nlmsg_flags = NLM_F_REQUEST; - req.n.nlmsg_type = delete ? XFRM_MSG_DELSA : XFRM_MSG_GETSA; - req.xsid.family = preferred_family; - - while (argc > 0) { - /* - * XXX: Source address is not used and ignore it to follow - * XXX: a manner of setkey e.g. in the case of deleting/getting - * XXX: message of IPsec SA. - */ - xfrm_address_t ignore_saddr; - - if (idp) - invarg("unknown", *argv); - idp = *argv; - - /* ID */ - memset(&id, 0, sizeof(id)); - xfrm_id_parse(&ignore_saddr, &id, &req.xsid.family, 0, - &argc, &argv); - - memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr)); - req.xsid.spi = id.spi; - req.xsid.proto = id.proto; - - argc--; argv++; - } - - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - - if (req.xsid.family == AF_UNSPEC) - req.xsid.family = AF_INET; - - if (delete) { - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - exit(2); - } else { - char buf[NLMSG_BUF_SIZE]; - struct nlmsghdr *res_n = (struct nlmsghdr *)buf; - - memset(buf, 0, sizeof(buf)); - - if (rtnl_talk(&rth, &req.n, 0, 0, res_n, NULL, NULL) < 0) - exit(2); - - if (xfrm_state_print(NULL, res_n, (void*)stdout) < 0) { - fprintf(stderr, "An error :-)\n"); - exit(1); - } - } - - rtnl_close(&rth); - - return 0; -} - -/* - * With an existing state of nlmsg, make new nlmsg for deleting the state - * and store it to buffer. - */ -static int xfrm_state_keep(const struct sockaddr_nl *who, - struct nlmsghdr *n, - void *arg) -{ - struct xfrm_buffer *xb = (struct xfrm_buffer *)arg; - struct rtnl_handle *rth = xb->rth; - struct xfrm_usersa_info *xsinfo = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct nlmsghdr *new_n; - struct xfrm_usersa_id *xsid; - - if (n->nlmsg_type != XFRM_MSG_NEWSA) { - fprintf(stderr, "Not a state: %08x %08x %08x\n", - n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags); - return 0; - } - - len -= NLMSG_LENGTH(sizeof(*xsinfo)); - if (len < 0) { - fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); - return -1; - } - - if (!xfrm_state_filter_match(xsinfo)) - return 0; - - if (xb->offset > xb->size) { - fprintf(stderr, "State buffer overflow\n"); - return -1; - } - - new_n = (struct nlmsghdr *)(xb->buf + xb->offset); - new_n->nlmsg_len = NLMSG_LENGTH(sizeof(*xsid)); - new_n->nlmsg_flags = NLM_F_REQUEST; - new_n->nlmsg_type = XFRM_MSG_DELSA; - new_n->nlmsg_seq = ++rth->seq; - - xsid = NLMSG_DATA(new_n); - xsid->family = xsinfo->family; - memcpy(&xsid->daddr, &xsinfo->id.daddr, sizeof(xsid->daddr)); - xsid->spi = xsinfo->id.spi; - xsid->proto = xsinfo->id.proto; - - xb->offset += new_n->nlmsg_len; - xb->nlmsg_count ++; - - return 0; -} - -static int xfrm_state_list_or_deleteall(int argc, char **argv, int deleteall) -{ - char *idp = NULL; - struct rtnl_handle rth; - - if(argc > 0) - filter.use = 1; - filter.xsinfo.family = preferred_family; - - while (argc > 0) { - if (strcmp(*argv, "mode") == 0) { - NEXT_ARG(); - xfrm_mode_parse(&filter.xsinfo.mode, &argc, &argv); - - filter.mode_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "reqid") == 0) { - NEXT_ARG(); - xfrm_reqid_parse(&filter.xsinfo.reqid, &argc, &argv); - - filter.reqid_mask = XFRM_FILTER_MASK_FULL; - - } else if (strcmp(*argv, "flag") == 0) { - NEXT_ARG(); - xfrm_state_flag_parse(&filter.xsinfo.flags, &argc, &argv); - - filter.state_flags_mask = XFRM_FILTER_MASK_FULL; - - } else { - if (idp) - invarg("unknown", *argv); - idp = *argv; - - /* ID */ - xfrm_id_parse(&filter.xsinfo.saddr, &filter.xsinfo.id, - &filter.xsinfo.family, 1, &argc, &argv); - if (preferred_family == AF_UNSPEC) - preferred_family = filter.xsinfo.family; - } - argc--; argv++; - } - - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - - if (deleteall) { - struct xfrm_buffer xb; - char buf[NLMSG_DELETEALL_BUF_SIZE]; - int i; - - xb.buf = buf; - xb.size = sizeof(buf); - xb.rth = &rth; - - for (i = 0; ; i++) { - xb.offset = 0; - xb.nlmsg_count = 0; - - if (show_stats > 1) - fprintf(stderr, "Delete-all round = %d\n", i); - - if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETSA) < 0) { - perror("Cannot send dump request"); - exit(1); - } - - if (rtnl_dump_filter(&rth, xfrm_state_keep, &xb, NULL, NULL) < 0) { - fprintf(stderr, "Delete-all terminated\n"); - exit(1); - } - if (xb.nlmsg_count == 0) { - if (show_stats > 1) - fprintf(stderr, "Delete-all completed\n"); - break; - } - - if (rtnl_send(&rth, xb.buf, xb.offset) < 0) { - perror("Failed to send delete-all request\n"); - exit(1); - } - if (show_stats > 1) - fprintf(stderr, "Delete-all nlmsg count = %d\n", xb.nlmsg_count); - - xb.offset = 0; - xb.nlmsg_count = 0; - } - - } else { - if (rtnl_wilddump_request(&rth, preferred_family, XFRM_MSG_GETSA) < 0) { - perror("Cannot send dump request"); - exit(1); - } - - if (rtnl_dump_filter(&rth, xfrm_state_print, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - exit(1); - } - } - - rtnl_close(&rth); - - exit(0); -} - -static int xfrm_state_flush(int argc, char **argv) -{ - struct rtnl_handle rth; - struct { - struct nlmsghdr n; - struct xfrm_usersa_flush xsf; - } req; - char *protop = NULL; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsf)); - req.n.nlmsg_flags = NLM_F_REQUEST; - req.n.nlmsg_type = XFRM_MSG_FLUSHSA; - req.xsf.proto = IPSEC_PROTO_ANY; - - while (argc > 0) { - if (strcmp(*argv, "proto") == 0) { - int ret; - - if (protop) - duparg("proto", *argv); - protop = *argv; - - NEXT_ARG(); - - ret = xfrm_xfrmproto_getbyname(*argv); - if (ret < 0) - invarg("\"XFRM_PROTO\" is invalid", *argv); - - req.xsf.proto = (__u8)ret; - } else - invarg("unknown", *argv); - - argc--; argv++; - } - - if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) - exit(1); - - if (show_stats > 1) - fprintf(stderr, "Flush state proto=%s\n", - (req.xsf.proto == IPSEC_PROTO_ANY) ? "any" : - strxf_xfrmproto(req.xsf.proto)); - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - exit(2); - - rtnl_close(&rth); - - return 0; -} - -int do_xfrm_state(int argc, char **argv) -{ - if (argc < 1) - return xfrm_state_list_or_deleteall(0, NULL, 0); - - if (matches(*argv, "add") == 0) - return xfrm_state_modify(XFRM_MSG_NEWSA, 0, - argc-1, argv+1); - if (matches(*argv, "update") == 0) - return xfrm_state_modify(XFRM_MSG_UPDSA, 0, - argc-1, argv+1); - if (matches(*argv, "allocspi") == 0) - return xfrm_state_allocspi(argc-1, argv+1); - if (matches(*argv, "delete") == 0) - return xfrm_state_get_or_delete(argc-1, argv+1, 1); - if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0) - return xfrm_state_list_or_deleteall(argc-1, argv+1, 1); - if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 - || matches(*argv, "lst") == 0) - return xfrm_state_list_or_deleteall(argc-1, argv+1, 0); - if (matches(*argv, "get") == 0) - return xfrm_state_get_or_delete(argc-1, argv+1, 0); - if (matches(*argv, "flush") == 0) - return xfrm_state_flush(argc-1, argv+1); - if (matches(*argv, "help") == 0) - usage(); - fprintf(stderr, "Command \"%s\" is unknown, try \"ip xfrm state help\".\n", *argv); - exit(-1); -} diff --git a/iproute.spec b/iproute.spec index 049dacd..89a6dca 100644 --- a/iproute.spec +++ b/iproute.spec @@ -4,11 +4,13 @@ %define url $URL$ %define name iproute -%define version 2.6.16 +%define version 2.6.33 %define taglevel 2 %define release %{taglevel}%{?pldistro:.%{pldistro}}%{?date:.%{date}} +%define cbq_version v0.7.3 + Vendor: PlanetLab Packager: PlanetLab Central <support@planet-lab.org> Distribution: PlanetLab %{plrelease} @@ -21,18 +23,7 @@ Release: %{release} Group: Applications/System #Source: http://developer.osdl.org/dev/iproute2/download/iproute2-%{version}-050314.tar.gz #URL: http://developer.osdl.org/dev/iproute2/ -Source: %{name}-%{version}.tar.gz -%define SOURCE1 ip.8 -%define SOURCE2 tc.8 -%define SOURCE3 tc-cbq.8 -%define SOURCE4 tc-cbq-details.8 -%define SOURCE5 tc-htb.8 -%define SOURCE6 tc-pbfifo.8 -%define SOURCE7 tc-pfifo_fast.8 -%define SOURCE8 tc-prio.8 -%define SOURCE9 tc-red.8 -%define SOURCE10 tc-sfq.8 -%define SOURCE11 tc-tbf.8 +Source: iproute2-%{version}.tar.bz2 License: GNU GPL BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildPrereq: tetex-latex tetex-dvips psutils linuxdoc-tools db4-devel bison flex @@ -43,7 +34,7 @@ example) which are designed to use the advanced networking capabilities of the Linux 2.4.x and 2.6.x kernel. %prep -%setup -q +%setup -q -n iproute2-%{version} %build make @@ -57,23 +48,16 @@ mkdir -p $RPM_BUILD_ROOT/sbin \ $RPM_BUILD_ROOT%{_sbindir} \ $RPM_BUILD_ROOT%{_mandir}/man8 \ $RPM_BUILD_ROOT/etc/iproute2 \ - $RPM_BUILD_ROOT%{_libdir}/tc + $RPM_BUILD_ROOT%{_datadir}/tc \ install -m 755 ip/ip ip/ifcfg ip/rtmon tc/tc $RPM_BUILD_ROOT/sbin install -m 755 misc/ss misc/nstat misc/rtacct misc/lnstat misc/arpd $RPM_BUILD_ROOT%{_sbindir} -install -m 755 tc/q_netem.so $RPM_BUILD_ROOT%{_libdir}/tc -install -m 644 netem/normal.dist netem/pareto.dist netem/paretonormal.dist $RPM_BUILD_ROOT%{_libdir}/tc -install -m 644 %{SOURCE1} $RPM_BUILD_ROOT/%{_mandir}/man8 -install -m 644 %{SOURCE2} $RPM_BUILD_ROOT/%{_mandir}/man8 -install -m 644 %{SOURCE3} $RPM_BUILD_ROOT/%{_mandir}/man8 -install -m 644 %{SOURCE4} $RPM_BUILD_ROOT/%{_mandir}/man8 -install -m 644 %{SOURCE5} $RPM_BUILD_ROOT/%{_mandir}/man8 -install -m 644 %{SOURCE6} $RPM_BUILD_ROOT/%{_mandir}/man8 -install -m 644 %{SOURCE7} $RPM_BUILD_ROOT/%{_mandir}/man8 -install -m 644 %{SOURCE8} $RPM_BUILD_ROOT/%{_mandir}/man8 -install -m 644 %{SOURCE9} $RPM_BUILD_ROOT/%{_mandir}/man8 -install -m 644 %{SOURCE10} $RPM_BUILD_ROOT/%{_mandir}/man8 -install -m 644 %{SOURCE11} $RPM_BUILD_ROOT/%{_mandir}/man8 +install -m 644 netem/normal.dist netem/pareto.dist netem/paretonormal.dist $RPM_BUILD_ROOT%{_datadir}/tc +install -m 644 man/man8/*.8 $RPM_BUILD_ROOT/%{_mandir}/man8 +rm -r $RPM_BUILD_ROOT/%{_mandir}/man8/ss.8 +iconv -f latin1 -t utf8 < man/man8/ss.8 > $RPM_BUILD_ROOT/%{_mandir}/man8/ss.8 +install -m 755 examples/cbq.init-%{cbq_version} $RPM_BUILD_ROOT/sbin/cbq +install -d -m 755 $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/cbq cp -f etc/iproute2/* $RPM_BUILD_ROOT/etc/iproute2 rm -rf $RPM_BUILD_ROOT/%{_libdir}/debug/* @@ -91,7 +75,8 @@ rm -rf $RPM_BUILD_ROOT/%{_libdir}/debug/* %{_mandir}/man8/* %attr(644,root,root) %config(noreplace) /etc/iproute2/* %{_sbindir}/* -%{_libdir}/tc/* +%dir %{_datadir}/tc +%{_datadir}/tc/* %changelog * Thu Jun 26 2008 Stephen Soltesz <soltesz@cs.princeton.edu> - iproute2-2.6.16-2 diff --git a/lib/Makefile b/lib/Makefile deleted file mode 100644 index bc270bf..0000000 --- a/lib/Makefile +++ /dev/null @@ -1,18 +0,0 @@ - -UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o - -NLOBJ=ll_map.o libnetlink.o - -all: libnetlink.a libutil.a - -libnetlink.a: $(NLOBJ) - $(AR) rcs $@ $(NLOBJ) - -libutil.a: $(UTILOBJ) $(ADDLIB) - $(AR) rcs $@ $(UTILOBJ) $(ADDLIB) - -install: - -clean: - rm -f $(NLOBJ) $(UTILOBJ) $(ADDLIB) libnetlink.a libutil.a - diff --git a/lib/dnet_ntop.c b/lib/dnet_ntop.c deleted file mode 100644 index 9500df8..0000000 --- a/lib/dnet_ntop.c +++ /dev/null @@ -1,98 +0,0 @@ -#include <errno.h> -#include <sys/types.h> -#include <netinet/in.h> - -#include "utils.h" - -static __inline__ u_int16_t dn_ntohs(u_int16_t addr) -{ - union { - u_int8_t byte[2]; - u_int16_t word; - } u; - - u.word = addr; - return ((u_int16_t)u.byte[0]) | (((u_int16_t)u.byte[1]) << 8); -} - -static __inline__ int do_digit(char *str, u_int16_t *addr, u_int16_t scale, size_t *pos, size_t len, int *started) -{ - u_int16_t tmp = *addr / scale; - - if (*pos == len) - return 1; - - if (((tmp) > 0) || *started || (scale == 1)) { - *str = tmp + '0'; - *started = 1; - (*pos)++; - *addr -= (tmp * scale); - } - - return 0; -} - - -static const char *dnet_ntop1(const struct dn_naddr *dna, char *str, size_t len) -{ - u_int16_t addr = dn_ntohs(*(u_int16_t *)dna->a_addr); - u_int16_t area = addr >> 10; - size_t pos = 0; - int started = 0; - - if (dna->a_len != 2) - return NULL; - - addr &= 0x03ff; - - if (len == 0) - return str; - - if (do_digit(str + pos, &area, 10, &pos, len, &started)) - return str; - - if (do_digit(str + pos, &area, 1, &pos, len, &started)) - return str; - - if (pos == len) - return str; - - *(str + pos) = '.'; - pos++; - started = 0; - - if (do_digit(str + pos, &addr, 1000, &pos, len, &started)) - return str; - - if (do_digit(str + pos, &addr, 100, &pos, len, &started)) - return str; - - if (do_digit(str + pos, &addr, 10, &pos, len, &started)) - return str; - - if (do_digit(str + pos, &addr, 1, &pos, len, &started)) - return str; - - if (pos == len) - return str; - - *(str + pos) = 0; - - return str; -} - - -const char *dnet_ntop(int af, const void *addr, char *str, size_t len) -{ - switch(af) { - case AF_DECnet: - errno = 0; - return dnet_ntop1((struct dn_naddr *)addr, str, len); - default: - errno = EAFNOSUPPORT; - } - - return NULL; -} - - diff --git a/lib/dnet_pton.c b/lib/dnet_pton.c deleted file mode 100644 index bd7727a..0000000 --- a/lib/dnet_pton.c +++ /dev/null @@ -1,71 +0,0 @@ -#include <errno.h> -#include <sys/types.h> -#include <netinet/in.h> - -#include "utils.h" - -static __inline__ u_int16_t dn_htons(u_int16_t addr) -{ - union { - u_int8_t byte[2]; - u_int16_t word; - } u; - - u.word = addr; - return ((u_int16_t)u.byte[0]) | (((u_int16_t)u.byte[1]) << 8); -} - - -static int dnet_num(const char *src, u_int16_t * dst) -{ - int rv = 0; - int tmp; - *dst = 0; - - while ((tmp = *src++) != 0) { - tmp -= '0'; - if ((tmp < 0) || (tmp > 9)) - return rv; - - rv++; - (*dst) *= 10; - (*dst) += tmp; - } - - return rv; -} - -static int dnet_pton1(const char *src, struct dn_naddr *dna) -{ - u_int16_t area = 0; - u_int16_t node = 0; - int pos; - - pos = dnet_num(src, &area); - if ((pos == 0) || (area > 63) || (*(src + pos) != '.')) - return 0; - pos = dnet_num(src + pos + 1, &node); - if ((pos == 0) || (node > 1023)) - return 0; - dna->a_len = 2; - *(u_int16_t *)dna->a_addr = dn_htons((area << 10) | node); - - return 1; -} - -int dnet_pton(int af, const char *src, void *addr) -{ - int err; - - switch (af) { - case AF_DECnet: - errno = 0; - err = dnet_pton1(src, (struct dn_naddr *)addr); - break; - default: - errno = EAFNOSUPPORT; - err = -1; - } - - return err; -} diff --git a/lib/inet_proto.c b/lib/inet_proto.c deleted file mode 100644 index a55e0e7..0000000 --- a/lib/inet_proto.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * inet_proto.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netdb.h> -#include <string.h> - -#include "utils.h" - -char *inet_proto_n2a(int proto, char *buf, int len) -{ - static char ncache[16]; - static int icache = -1; - struct protoent *pe; - - if (proto == icache) - return ncache; - - pe = getprotobynumber(proto); - if (pe) { - icache = proto; - strncpy(ncache, pe->p_name, 16); - strncpy(buf, pe->p_name, len); - return buf; - } - snprintf(buf, len, "ipproto-%d", proto); - return buf; -} - -int inet_proto_a2n(char *buf) -{ - static char ncache[16]; - static int icache = -1; - struct protoent *pe; - - if (icache>=0 && strcmp(ncache, buf) == 0) - return icache; - - if (buf[0] >= '0' && buf[0] <= '9') { - __u8 ret; - if (get_u8(&ret, buf, 10)) - return -1; - return ret; - } - - pe = getprotobyname(buf); - if (pe) { - icache = pe->p_proto; - strncpy(ncache, pe->p_name, 16); - return pe->p_proto; - } - return -1; -} - - diff --git a/lib/ipx_ntop.c b/lib/ipx_ntop.c deleted file mode 100644 index b2d6790..0000000 --- a/lib/ipx_ntop.c +++ /dev/null @@ -1,71 +0,0 @@ -#include <errno.h> -#include <sys/types.h> -#include <netinet/in.h> - -#include "utils.h" - -static __inline__ int do_digit(char *str, u_int32_t addr, u_int32_t scale, size_t *pos, size_t len) -{ - u_int32_t tmp = addr >> (scale * 4); - - if (*pos == len) - return 1; - - tmp &= 0x0f; - if (tmp > 9) - *str = tmp + 'A' - 10; - else - *str = tmp + '0'; - (*pos)++; - - return 0; -} - -static const char *ipx_ntop1(const struct ipx_addr *addr, char *str, size_t len) -{ - int i; - size_t pos = 0; - - if (len == 0) - return str; - - for(i = 7; i >= 0; i--) - if (do_digit(str + pos, ntohl(addr->ipx_net), i, &pos, len)) - return str; - - if (pos == len) - return str; - - *(str + pos) = '.'; - pos++; - - for(i = 0; i < 6; i++) { - if (do_digit(str + pos, addr->ipx_node[i], 1, &pos, len)) - return str; - if (do_digit(str + pos, addr->ipx_node[i], 0, &pos, len)) - return str; - } - - if (pos == len) - return str; - - *(str + pos) = 0; - - return str; -} - - -const char *ipx_ntop(int af, const void *addr, char *str, size_t len) -{ - switch(af) { - case AF_IPX: - errno = 0; - return ipx_ntop1((struct ipx_addr *)addr, str, len); - default: - errno = EAFNOSUPPORT; - } - - return NULL; -} - - diff --git a/lib/ipx_pton.c b/lib/ipx_pton.c deleted file mode 100644 index 1a52b7f..0000000 --- a/lib/ipx_pton.c +++ /dev/null @@ -1,107 +0,0 @@ -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <netinet/in.h> - -#include "utils.h" - -static u_int32_t hexget(char c) -{ - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - if (c >= '0' && c <= '9') - return c - '0'; - - return 0xf0; -} - -static int ipx_getnet(u_int32_t *net, const char *str) -{ - int i; - u_int32_t tmp; - - for(i = 0; *str && (i < 8); i++) { - - if ((tmp = hexget(*str)) & 0xf0) { - if (*str == '.') - return 0; - else - return -1; - } - - str++; - (*net) <<= 4; - (*net) |= tmp; - } - - if (*str == 0) - return 0; - - return -1; -} - -static int ipx_getnode(u_int8_t *node, const char *str) -{ - int i; - u_int32_t tmp; - - for(i = 0; i < 6; i++) { - if ((tmp = hexget(*str++)) & 0xf0) - return -1; - node[i] = (u_int8_t)tmp; - node[i] <<= 4; - if ((tmp = hexget(*str++)) & 0xf0) - return -1; - node[i] |= (u_int8_t)tmp; - if (*str == ':') - str++; - } - - return 0; -} - -static int ipx_pton1(const char *src, struct ipx_addr *addr) -{ - char *sep = (char *)src; - int no_node = 0; - - memset(addr, 0, sizeof(struct ipx_addr)); - - while(*sep && (*sep != '.')) - sep++; - - if (*sep != '.') - no_node = 1; - - if (ipx_getnet(&addr->ipx_net, src)) - return 0; - - addr->ipx_net = htonl(addr->ipx_net); - - if (no_node) - return 1; - - if (ipx_getnode(addr->ipx_node, sep + 1)) - return 0; - - return 1; -} - -int ipx_pton(int af, const char *src, void *addr) -{ - int err; - - switch (af) { - case AF_IPX: - errno = 0; - err = ipx_pton1(src, (struct ipx_addr *)addr); - break; - default: - errno = EAFNOSUPPORT; - err = -1; - } - - return err; -} diff --git a/lib/libnetlink.c b/lib/libnetlink.c deleted file mode 100644 index 67951fe..0000000 --- a/lib/libnetlink.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * libnetlink.c RTnetlink service routines. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <net/if_arp.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <sys/uio.h> - -#include "libnetlink.h" - -void rtnl_close(struct rtnl_handle *rth) -{ - close(rth->fd); -} - -int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, - int protocol) -{ - socklen_t addr_len; - int sndbuf = 32768; - int rcvbuf = 32768; - - memset(rth, 0, sizeof(rth)); - - rth->fd = socket(AF_NETLINK, SOCK_RAW, protocol); - if (rth->fd < 0) { - perror("Cannot open netlink socket"); - return -1; - } - - if (setsockopt(rth->fd,SOL_SOCKET,SO_SNDBUF,&sndbuf,sizeof(sndbuf)) < 0) { - perror("SO_SNDBUF"); - return -1; - } - - if (setsockopt(rth->fd,SOL_SOCKET,SO_RCVBUF,&rcvbuf,sizeof(rcvbuf)) < 0) { - perror("SO_RCVBUF"); - return -1; - } - - memset(&rth->local, 0, sizeof(rth->local)); - rth->local.nl_family = AF_NETLINK; - rth->local.nl_groups = subscriptions; - - if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) { - perror("Cannot bind netlink socket"); - return -1; - } - addr_len = sizeof(rth->local); - if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) { - perror("Cannot getsockname"); - return -1; - } - if (addr_len != sizeof(rth->local)) { - fprintf(stderr, "Wrong address length %d\n", addr_len); - return -1; - } - if (rth->local.nl_family != AF_NETLINK) { - fprintf(stderr, "Wrong address family %d\n", rth->local.nl_family); - return -1; - } - rth->seq = time(NULL); - return 0; -} - -int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions) -{ - return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE); -} - -int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) -{ - struct { - struct nlmsghdr nlh; - struct rtgenmsg g; - } req; - struct sockaddr_nl nladdr; - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - - memset(&req, 0, sizeof(req)); - req.nlh.nlmsg_len = sizeof(req); - req.nlh.nlmsg_type = type; - req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; - req.nlh.nlmsg_pid = 0; - req.nlh.nlmsg_seq = rth->dump = ++rth->seq; - req.g.rtgen_family = family; - - return sendto(rth->fd, (void*)&req, sizeof(req), 0, - (struct sockaddr*)&nladdr, sizeof(nladdr)); -} - -int rtnl_send(struct rtnl_handle *rth, const char *buf, int len) -{ - struct sockaddr_nl nladdr; - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - - return sendto(rth->fd, buf, len, 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); -} - -int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) -{ - struct nlmsghdr nlh; - struct sockaddr_nl nladdr; - struct iovec iov[2] = { - { .iov_base = &nlh, .iov_len = sizeof(nlh) }, - { .iov_base = req, .iov_len = len } - }; - struct msghdr msg = { - .msg_name = &nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = iov, - .msg_iovlen = 2, - }; - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - - nlh.nlmsg_len = NLMSG_LENGTH(len); - nlh.nlmsg_type = type; - nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; - nlh.nlmsg_pid = 0; - nlh.nlmsg_seq = rth->dump = ++rth->seq; - - return sendmsg(rth->fd, &msg, 0); -} - -int rtnl_dump_filter(struct rtnl_handle *rth, - rtnl_filter_t filter, - void *arg1, - rtnl_filter_t junk, - void *arg2) -{ - struct sockaddr_nl nladdr; - struct iovec iov; - struct msghdr msg = { - .msg_name = &nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = &iov, - .msg_iovlen = 1, - }; - char buf[16384]; - - iov.iov_base = buf; - while (1) { - int status; - struct nlmsghdr *h; - - iov.iov_len = sizeof(buf); - status = recvmsg(rth->fd, &msg, 0); - - if (status < 0) { - if (errno == EINTR) - continue; - perror("OVERRUN"); - continue; - } - - if (status == 0) { - fprintf(stderr, "EOF on netlink\n"); - return -1; - } - - h = (struct nlmsghdr*)buf; - while (NLMSG_OK(h, status)) { - int err; - - if (nladdr.nl_pid != 0 || - h->nlmsg_pid != rth->local.nl_pid || - h->nlmsg_seq != rth->dump) { - if (junk) { - err = junk(&nladdr, h, arg2); - if (err < 0) - return err; - } - goto skip_it; - } - - if (h->nlmsg_type == NLMSG_DONE) - return 0; - if (h->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); - if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { - fprintf(stderr, "ERROR truncated\n"); - } else { - errno = -err->error; - perror("RTNETLINK answers"); - } - return -1; - } - err = filter(&nladdr, h, arg1); - if (err < 0) - return err; - -skip_it: - h = NLMSG_NEXT(h, status); - } - if (msg.msg_flags & MSG_TRUNC) { - fprintf(stderr, "Message truncated\n"); - continue; - } - if (status) { - fprintf(stderr, "!!!Remnant of size %d\n", status); - exit(1); - } - } -} - -int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, - unsigned groups, struct nlmsghdr *answer, - rtnl_filter_t junk, - void *jarg) -{ - int status; - unsigned seq; - struct nlmsghdr *h; - struct sockaddr_nl nladdr; - struct iovec iov = { - .iov_base = (void*) n, - .iov_len = n->nlmsg_len - }; - struct msghdr msg = { - .msg_name = &nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = &iov, - .msg_iovlen = 1, - }; - char buf[16384]; - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - nladdr.nl_pid = peer; - nladdr.nl_groups = groups; - - n->nlmsg_seq = seq = ++rtnl->seq; - - if (answer == NULL) - n->nlmsg_flags |= NLM_F_ACK; - - status = sendmsg(rtnl->fd, &msg, 0); - - if (status < 0) { - perror("Cannot talk to rtnetlink"); - return -1; - } - - memset(buf,0,sizeof(buf)); - - iov.iov_base = buf; - - while (1) { - iov.iov_len = sizeof(buf); - status = recvmsg(rtnl->fd, &msg, 0); - - if (status < 0) { - if (errno == EINTR) - continue; - perror("OVERRUN"); - continue; - } - if (status == 0) { - fprintf(stderr, "EOF on netlink\n"); - return -1; - } - if (msg.msg_namelen != sizeof(nladdr)) { - fprintf(stderr, "sender address length == %d\n", msg.msg_namelen); - exit(1); - } - for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) { - int err; - int len = h->nlmsg_len; - int l = len - sizeof(*h); - - if (l<0 || len>status) { - if (msg.msg_flags & MSG_TRUNC) { - fprintf(stderr, "Truncated message\n"); - return -1; - } - fprintf(stderr, "!!!malformed message: len=%d\n", len); - exit(1); - } - - if (nladdr.nl_pid != peer || - h->nlmsg_pid != rtnl->local.nl_pid || - h->nlmsg_seq != seq) { - if (junk) { - err = junk(&nladdr, h, jarg); - if (err < 0) - return err; - } - /* Don't forget to skip that message. */ - status -= NLMSG_ALIGN(len); - h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); - continue; - } - - if (h->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); - if (l < sizeof(struct nlmsgerr)) { - fprintf(stderr, "ERROR truncated\n"); - } else { - errno = -err->error; - if (errno == 0) { - if (answer) - memcpy(answer, h, h->nlmsg_len); - return 0; - } - perror("RTNETLINK answers"); - } - return -1; - } - if (answer) { - memcpy(answer, h, h->nlmsg_len); - return 0; - } - - fprintf(stderr, "Unexpected reply!!!\n"); - - status -= NLMSG_ALIGN(len); - h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); - } - if (msg.msg_flags & MSG_TRUNC) { - fprintf(stderr, "Message truncated\n"); - continue; - } - if (status) { - fprintf(stderr, "!!!Remnant of size %d\n", status); - exit(1); - } - } -} - -int rtnl_listen(struct rtnl_handle *rtnl, - rtnl_filter_t handler, - void *jarg) -{ - int status; - struct nlmsghdr *h; - struct sockaddr_nl nladdr; - struct iovec iov; - struct msghdr msg = { - .msg_name = &nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = &iov, - .msg_iovlen = 1, - }; - char buf[8192]; - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - nladdr.nl_pid = 0; - nladdr.nl_groups = 0; - - iov.iov_base = buf; - while (1) { - iov.iov_len = sizeof(buf); - status = recvmsg(rtnl->fd, &msg, 0); - - if (status < 0) { - if (errno == EINTR) - continue; - perror("OVERRUN"); - continue; - } - if (status == 0) { - fprintf(stderr, "EOF on netlink\n"); - return -1; - } - if (msg.msg_namelen != sizeof(nladdr)) { - fprintf(stderr, "Sender address length == %d\n", msg.msg_namelen); - exit(1); - } - for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) { - int err; - int len = h->nlmsg_len; - int l = len - sizeof(*h); - - if (l<0 || len>status) { - if (msg.msg_flags & MSG_TRUNC) { - fprintf(stderr, "Truncated message\n"); - return -1; - } - fprintf(stderr, "!!!malformed message: len=%d\n", len); - exit(1); - } - - err = handler(&nladdr, h, jarg); - if (err < 0) - return err; - - status -= NLMSG_ALIGN(len); - h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); - } - if (msg.msg_flags & MSG_TRUNC) { - fprintf(stderr, "Message truncated\n"); - continue; - } - if (status) { - fprintf(stderr, "!!!Remnant of size %d\n", status); - exit(1); - } - } -} - -int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler, - void *jarg) -{ - int status; - struct sockaddr_nl nladdr; - char buf[8192]; - struct nlmsghdr *h = (void*)buf; - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - nladdr.nl_pid = 0; - nladdr.nl_groups = 0; - - while (1) { - int err, len, type; - int l; - - status = fread(&buf, 1, sizeof(*h), rtnl); - - if (status < 0) { - if (errno == EINTR) - continue; - perror("rtnl_from_file: fread"); - return -1; - } - if (status == 0) - return 0; - - len = h->nlmsg_len; - type= h->nlmsg_type; - l = len - sizeof(*h); - - if (l<0 || len>sizeof(buf)) { - fprintf(stderr, "!!!malformed message: len=%d @%lu\n", - len, ftell(rtnl)); - return -1; - } - - status = fread(NLMSG_DATA(h), 1, NLMSG_ALIGN(l), rtnl); - - if (status < 0) { - perror("rtnl_from_file: fread"); - return -1; - } - if (status < l) { - fprintf(stderr, "rtnl-from_file: truncated message\n"); - return -1; - } - - err = handler(&nladdr, h, jarg); - if (err < 0) - return err; - } -} - -int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data) -{ - int len = RTA_LENGTH(4); - struct rtattr *rta; - if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) { - fprintf(stderr,"addattr32: Error! max allowed bound %d exceeded\n",maxlen); - return -1; - } - rta = NLMSG_TAIL(n); - rta->rta_type = type; - rta->rta_len = len; - memcpy(RTA_DATA(rta), &data, 4); - n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len; - return 0; -} - -int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, - int alen) -{ - int len = RTA_LENGTH(alen); - struct rtattr *rta; - - if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) { - fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen); - return -1; - } - rta = NLMSG_TAIL(n); - rta->rta_type = type; - rta->rta_len = len; - memcpy(RTA_DATA(rta), data, alen); - n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); - return 0; -} - -int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len) -{ - if (NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len) > maxlen) { - fprintf(stderr, "addraw_l ERROR: message exceeded bound of %d\n",maxlen); - return -1; - } - - memcpy(NLMSG_TAIL(n), data, len); - memset((void *) NLMSG_TAIL(n) + len, 0, NLMSG_ALIGN(len) - len); - n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len); - return 0; -} - -int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data) -{ - int len = RTA_LENGTH(4); - struct rtattr *subrta; - - if (RTA_ALIGN(rta->rta_len) + len > maxlen) { - fprintf(stderr,"rta_addattr32: Error! max allowed bound %d exceeded\n",maxlen); - return -1; - } - subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); - subrta->rta_type = type; - subrta->rta_len = len; - memcpy(RTA_DATA(subrta), &data, 4); - rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len; - return 0; -} - -int rta_addattr_l(struct rtattr *rta, int maxlen, int type, - const void *data, int alen) -{ - struct rtattr *subrta; - int len = RTA_LENGTH(alen); - - if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) { - fprintf(stderr,"rta_addattr_l: Error! max allowed bound %d exceeded\n",maxlen); - return -1; - } - subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); - subrta->rta_type = type; - subrta->rta_len = len; - memcpy(RTA_DATA(subrta), data, alen); - rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len); - return 0; -} - -int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) -{ - memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); - while (RTA_OK(rta, len)) { - if (rta->rta_type <= max) - tb[rta->rta_type] = rta; - rta = RTA_NEXT(rta,len); - } - if (len) - fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len); - return 0; -} - -int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len) -{ - int i = 0; - - memset(tb, 0, sizeof(struct rtattr *) * max); - while (RTA_OK(rta, len)) { - if (rta->rta_type <= max && i < max) - tb[i++] = rta; - rta = RTA_NEXT(rta,len); - } - if (len) - fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len); - return i; -} diff --git a/lib/ll_addr.c b/lib/ll_addr.c deleted file mode 100644 index 581487d..0000000 --- a/lib/ll_addr.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * ll_addr.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include <linux/netdevice.h> -#include <linux/if_arp.h> -#include <linux/sockios.h> - -#include "rt_names.h" -#include "utils.h" - - -const char *ll_addr_n2a(unsigned char *addr, int alen, int type, char *buf, int blen) -{ - int i; - int l; - - if (alen == 4 && - (type == ARPHRD_TUNNEL || type == ARPHRD_SIT || type == ARPHRD_IPGRE)) { - return inet_ntop(AF_INET, addr, buf, blen); - } - l = 0; - for (i=0; i<alen; i++) { - if (i==0) { - snprintf(buf+l, blen, "%02x", addr[i]); - blen -= 2; - l += 2; - } else { - snprintf(buf+l, blen, ":%02x", addr[i]); - blen -= 3; - l += 3; - } - } - return buf; -} - -/*NB: lladdr is char * (rather than u8 *) because sa_data is char * (1003.1g) */ -int ll_addr_a2n(char *lladdr, int len, char *arg) -{ - if (strchr(arg, '.')) { - inet_prefix pfx; - if (get_addr_1(&pfx, arg, AF_INET)) { - fprintf(stderr, "\"%s\" is invalid lladdr.\n", arg); - return -1; - } - if (len < 4) - return -1; - memcpy(lladdr, pfx.data, 4); - return 4; - } else { - int i; - - for (i=0; i<len; i++) { - int temp; - char *cp = strchr(arg, ':'); - if (cp) { - *cp = 0; - cp++; - } - if (sscanf(arg, "%x", &temp) != 1) { - fprintf(stderr, "\"%s\" is invalid lladdr.\n", arg); - return -1; - } - if (temp < 0 || temp > 255) { - fprintf(stderr, "\"%s\" is invalid lladdr.\n", arg); - return -1; - } - lladdr[i] = temp; - if (!cp) - break; - arg = cp; - } - return i+1; - } -} diff --git a/lib/ll_map.c b/lib/ll_map.c deleted file mode 100644 index 1acbf8f..0000000 --- a/lib/ll_map.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * ll_map.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <net/if.h> -#include <string.h> - -#include "libnetlink.h" -#include "ll_map.h" - -struct idxmap -{ - struct idxmap * next; - unsigned index; - int type; - int alen; - unsigned flags; - unsigned char addr[8]; - char name[16]; -}; - -static struct idxmap *idxmap[16]; - -int ll_remember_index(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg) -{ - int h; - struct ifinfomsg *ifi = NLMSG_DATA(n); - struct idxmap *im, **imp; - struct rtattr *tb[IFLA_MAX+1]; - - if (n->nlmsg_type != RTM_NEWLINK) - return 0; - - if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi))) - return -1; - - - memset(tb, 0, sizeof(tb)); - parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n)); - if (tb[IFLA_IFNAME] == NULL) - return 0; - - h = ifi->ifi_index&0xF; - - for (imp=&idxmap[h]; (im=*imp)!=NULL; imp = &im->next) - if (im->index == ifi->ifi_index) - break; - - if (im == NULL) { - im = malloc(sizeof(*im)); - if (im == NULL) - return 0; - im->next = *imp; - im->index = ifi->ifi_index; - *imp = im; - } - - im->type = ifi->ifi_type; - im->flags = ifi->ifi_flags; - if (tb[IFLA_ADDRESS]) { - int alen; - im->alen = alen = RTA_PAYLOAD(tb[IFLA_ADDRESS]); - if (alen > sizeof(im->addr)) - alen = sizeof(im->addr); - memcpy(im->addr, RTA_DATA(tb[IFLA_ADDRESS]), alen); - } else { - im->alen = 0; - memset(im->addr, 0, sizeof(im->addr)); - } - strcpy(im->name, RTA_DATA(tb[IFLA_IFNAME])); - return 0; -} - -const char *ll_idx_n2a(unsigned idx, char *buf) -{ - struct idxmap *im; - - if (idx == 0) - return "*"; - for (im = idxmap[idx&0xF]; im; im = im->next) - if (im->index == idx) - return im->name; - snprintf(buf, 16, "if%d", idx); - return buf; -} - - -const char *ll_index_to_name(unsigned idx) -{ - static char nbuf[16]; - - return ll_idx_n2a(idx, nbuf); -} - -int ll_index_to_type(unsigned idx) -{ - struct idxmap *im; - - if (idx == 0) - return -1; - for (im = idxmap[idx&0xF]; im; im = im->next) - if (im->index == idx) - return im->type; - return -1; -} - -unsigned ll_index_to_flags(unsigned idx) -{ - struct idxmap *im; - - if (idx == 0) - return 0; - - for (im = idxmap[idx&0xF]; im; im = im->next) - if (im->index == idx) - return im->flags; - return 0; -} - -unsigned ll_name_to_index(const char *name) -{ - static char ncache[16]; - static int icache; - struct idxmap *im; - int i; - - if (name == NULL) - return 0; - if (icache && strcmp(name, ncache) == 0) - return icache; - for (i=0; i<16; i++) { - for (im = idxmap[i]; im; im = im->next) { - if (strcmp(im->name, name) == 0) { - icache = im->index; - strcpy(ncache, name); - return im->index; - } - } - } - - return if_nametoindex(name); -} - -int ll_init_map(struct rtnl_handle *rth) -{ - if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) { - perror("Cannot send dump request"); - exit(1); - } - - if (rtnl_dump_filter(rth, ll_remember_index, &idxmap, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - exit(1); - } - return 0; -} diff --git a/lib/ll_proto.c b/lib/ll_proto.c deleted file mode 100644 index 98c67fe..0000000 --- a/lib/ll_proto.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * ll_proto.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include <linux/netdevice.h> -#include <linux/if_arp.h> -#include <linux/sockios.h> - -#include "utils.h" -#include "rt_names.h" - - -#define __PF(f,n) { ETH_P_##f, #n }, -static struct { - int id; - const char *name; -} llproto_names[] = { -__PF(LOOP,loop) -__PF(PUP,pup) -#ifdef ETH_P_PUPAT -__PF(PUPAT,pupat) -#endif -__PF(IP,ip) -__PF(X25,x25) -__PF(ARP,arp) -__PF(BPQ,bpq) -#ifdef ETH_P_IEEEPUP -__PF(IEEEPUP,ieeepup) -#endif -#ifdef ETH_P_IEEEPUPAT -__PF(IEEEPUPAT,ieeepupat) -#endif -__PF(DEC,dec) -__PF(DNA_DL,dna_dl) -__PF(DNA_RC,dna_rc) -__PF(DNA_RT,dna_rt) -__PF(LAT,lat) -__PF(DIAG,diag) -__PF(CUST,cust) -__PF(SCA,sca) -__PF(RARP,rarp) -__PF(ATALK,atalk) -__PF(AARP,aarp) -__PF(IPX,ipx) -__PF(IPV6,ipv6) -#ifdef ETH_P_PPP_DISC -__PF(PPP_DISC,ppp_disc) -#endif -#ifdef ETH_P_PPP_SES -__PF(PPP_SES,ppp_ses) -#endif -#ifdef ETH_P_ATMMPOA -__PF(ATMMPOA,atmmpoa) -#endif -#ifdef ETH_P_ATMFATE -__PF(ATMFATE,atmfate) -#endif - -__PF(802_3,802_3) -__PF(AX25,ax25) -__PF(ALL,all) -__PF(802_2,802_2) -__PF(SNAP,snap) -__PF(DDCMP,ddcmp) -__PF(WAN_PPP,wan_ppp) -__PF(PPP_MP,ppp_mp) -__PF(LOCALTALK,localtalk) -__PF(PPPTALK,ppptalk) -__PF(TR_802_2,tr_802_2) -__PF(MOBITEX,mobitex) -__PF(CONTROL,control) -__PF(IRDA,irda) -#ifdef ETH_P_ECONET -__PF(ECONET,econet) -#endif - -{ 0x8100, "802.1Q" }, -{ ETH_P_IP, "ipv4" }, -}; -#undef __PF - - -const char * ll_proto_n2a(unsigned short id, char *buf, int len) -{ - int i; - - id = ntohs(id); - - for (i=0; i<sizeof(llproto_names)/sizeof(llproto_names[0]); i++) { - if (llproto_names[i].id == id) - return llproto_names[i].name; - } - snprintf(buf, len, "[%d]", id); - return buf; -} - -int ll_proto_a2n(unsigned short *id, char *buf) -{ - int i; - for (i=0; i<sizeof(llproto_names)/sizeof(llproto_names[0]); i++) { - if (strcasecmp(llproto_names[i].name, buf) == 0) { - *id = htons(llproto_names[i].id); - return 0; - } - } - if (get_u16(id, buf, 0)) - return -1; - *id = htons(*id); - return 0; -} diff --git a/lib/ll_types.c b/lib/ll_types.c deleted file mode 100644 index 5b0f106..0000000 --- a/lib/ll_types.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * ll_types.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include <linux/netdevice.h> -#include <linux/if_arp.h> -#include <linux/sockios.h> - -#include "rt_names.h" - -const char * ll_type_n2a(int type, char *buf, int len) -{ -#define __PF(f,n) { ARPHRD_##f, #n }, -static struct { - int type; - const char *name; -} arphrd_names[] = { -{ 0, "generic" }, -__PF(ETHER,ether) -__PF(EETHER,eether) -__PF(AX25,ax25) -__PF(PRONET,pronet) -__PF(CHAOS,chaos) -#ifdef ARPHRD_IEEE802_TR -__PF(IEEE802,ieee802) -#else -__PF(IEEE802,tr) -#endif -__PF(ARCNET,arcnet) -__PF(APPLETLK,atalk) -__PF(DLCI,dlci) -#ifdef ARPHRD_ATM -__PF(ATM,atm) -#endif -__PF(METRICOM,metricom) -#ifdef ARPHRD_IEEE1394 -__PF(IEEE1394,ieee1394) -#endif -#ifdef ARPHRD_INFINIBAND -__PF(INFINIBAND,infiniband) -#endif - -__PF(SLIP,slip) -__PF(CSLIP,cslip) -__PF(SLIP6,slip6) -__PF(CSLIP6,cslip6) -__PF(RSRVD,rsrvd) -__PF(ADAPT,adapt) -__PF(ROSE,rose) -__PF(X25,x25) -#ifdef ARPHRD_HWX25 -__PF(HWX25,hwx25) -#endif -__PF(PPP,ppp) -__PF(HDLC,hdlc) -__PF(LAPB,lapb) -#ifdef ARPHRD_DDCMP -__PF(DDCMP,ddcmp) -#endif -#ifdef ARPHRD_RAWHDLC -__PF(RAWHDLC,rawhdlc) -#endif - -__PF(TUNNEL,ipip) -__PF(TUNNEL6,tunnel6) -__PF(FRAD,frad) -__PF(SKIP,skip) -__PF(LOOPBACK,loopback) -__PF(LOCALTLK,ltalk) -__PF(FDDI,fddi) -__PF(BIF,bif) -__PF(SIT,sit) -__PF(IPDDP,ip/ddp) -__PF(IPGRE,gre) -__PF(PIMREG,pimreg) -__PF(HIPPI,hippi) -__PF(ASH,ash) -__PF(ECONET,econet) -__PF(IRDA,irda) -__PF(FCPP,fcpp) -__PF(FCAL,fcal) -__PF(FCPL,fcpl) -__PF(FCFABRIC,fcfb0) -__PF(FCFABRIC+1,fcfb1) -__PF(FCFABRIC+2,fcfb2) -__PF(FCFABRIC+3,fcfb3) -__PF(FCFABRIC+4,fcfb4) -__PF(FCFABRIC+5,fcfb5) -__PF(FCFABRIC+6,fcfb6) -__PF(FCFABRIC+7,fcfb7) -__PF(FCFABRIC+8,fcfb8) -__PF(FCFABRIC+9,fcfb9) -__PF(FCFABRIC+10,fcfb10) -__PF(FCFABRIC+11,fcfb11) -__PF(FCFABRIC+12,fcfb12) -#ifdef ARPHRD_IEEE802_TR -__PF(IEEE802_TR,tr) -#endif -#ifdef ARPHRD_IEEE80211 -__PF(IEEE80211,ieee802.11) -#endif -#ifdef ARPHRD_VOID -__PF(VOID,void) -#endif -}; -#undef __PF - - int i; - for (i=0; i<sizeof(arphrd_names)/sizeof(arphrd_names[0]); i++) { - if (arphrd_names[i].type == type) - return arphrd_names[i].name; - } - snprintf(buf, len, "[%d]", type); - return buf; -} diff --git a/lib/rt_names.c b/lib/rt_names.c deleted file mode 100644 index 05046c2..0000000 --- a/lib/rt_names.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * rt_names.c rtnetlink names DB. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <string.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <asm/types.h> -#include <linux/rtnetlink.h> - -#include "rt_names.h" - -static void rtnl_tab_initialize(char *file, char **tab, int size) -{ - char buf[512]; - FILE *fp; - - fp = fopen(file, "r"); - if (!fp) - return; - while (fgets(buf, sizeof(buf), fp)) { - char *p = buf; - int id; - char namebuf[512]; - - while (*p == ' ' || *p == '\t') - p++; - if (*p == '#' || *p == '\n' || *p == 0) - continue; - if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 && - sscanf(p, "0x%x %s #", &id, namebuf) != 2 && - sscanf(p, "%d %s\n", &id, namebuf) != 2 && - sscanf(p, "%d %s #", &id, namebuf) != 2) { - fprintf(stderr, "Database %s is corrupted at %s\n", - file, p); - return; - } - - if (id<0 || id>size) - continue; - - tab[id] = strdup(namebuf); - } - fclose(fp); -} - - -static char * rtnl_rtprot_tab[256] = { - [RTPROT_UNSPEC] = "none", - [RTPROT_REDIRECT] ="redirect", - [RTPROT_KERNEL] = "kernel", - [RTPROT_BOOT] = "boot", - [RTPROT_STATIC] = "static", - - [RTPROT_GATED] = "gated", - [RTPROT_RA] = "ra", - [RTPROT_MRT] = "mrt", - [RTPROT_ZEBRA] ="zebra", - [RTPROT_BIRD] = "bird", - [RTPROT_DNROUTED] = "dnrouted", - [RTPROT_XORP] = "xorp", - [RTPROT_NTK] = "ntk", -}; - - - -static int rtnl_rtprot_init; - -static void rtnl_rtprot_initialize(void) -{ - rtnl_rtprot_init = 1; - rtnl_tab_initialize("/etc/iproute2/rt_protos", - rtnl_rtprot_tab, 256); -} - -char * rtnl_rtprot_n2a(int id, char *buf, int len) -{ - if (id<0 || id>=256) { - snprintf(buf, len, "%d", id); - return buf; - } - if (!rtnl_rtprot_tab[id]) { - if (!rtnl_rtprot_init) - rtnl_rtprot_initialize(); - } - if (rtnl_rtprot_tab[id]) - return rtnl_rtprot_tab[id]; - snprintf(buf, len, "%d", id); - return buf; -} - -int rtnl_rtprot_a2n(__u32 *id, char *arg) -{ - static char *cache = NULL; - static unsigned long res; - char *end; - int i; - - if (cache && strcmp(cache, arg) == 0) { - *id = res; - return 0; - } - - if (!rtnl_rtprot_init) - rtnl_rtprot_initialize(); - - for (i=0; i<256; i++) { - if (rtnl_rtprot_tab[i] && - strcmp(rtnl_rtprot_tab[i], arg) == 0) { - cache = rtnl_rtprot_tab[i]; - res = i; - *id = res; - return 0; - } - } - - res = strtoul(arg, &end, 0); - if (!end || end == arg || *end || res > 255) - return -1; - *id = res; - return 0; -} - - - -static char * rtnl_rtscope_tab[256] = { - "global", -}; - -static int rtnl_rtscope_init; - -static void rtnl_rtscope_initialize(void) -{ - rtnl_rtscope_init = 1; - rtnl_rtscope_tab[255] = "nowhere"; - rtnl_rtscope_tab[254] = "host"; - rtnl_rtscope_tab[253] = "link"; - rtnl_rtscope_tab[200] = "site"; - rtnl_tab_initialize("/etc/iproute2/rt_scopes", - rtnl_rtscope_tab, 256); -} - -char * rtnl_rtscope_n2a(int id, char *buf, int len) -{ - if (id<0 || id>=256) { - snprintf(buf, len, "%d", id); - return buf; - } - if (!rtnl_rtscope_tab[id]) { - if (!rtnl_rtscope_init) - rtnl_rtscope_initialize(); - } - if (rtnl_rtscope_tab[id]) - return rtnl_rtscope_tab[id]; - snprintf(buf, len, "%d", id); - return buf; -} - -int rtnl_rtscope_a2n(__u32 *id, char *arg) -{ - static char *cache = NULL; - static unsigned long res; - char *end; - int i; - - if (cache && strcmp(cache, arg) == 0) { - *id = res; - return 0; - } - - if (!rtnl_rtscope_init) - rtnl_rtscope_initialize(); - - for (i=0; i<256; i++) { - if (rtnl_rtscope_tab[i] && - strcmp(rtnl_rtscope_tab[i], arg) == 0) { - cache = rtnl_rtscope_tab[i]; - res = i; - *id = res; - return 0; - } - } - - res = strtoul(arg, &end, 0); - if (!end || end == arg || *end || res > 255) - return -1; - *id = res; - return 0; -} - - - -static char * rtnl_rtrealm_tab[256] = { - "unknown", -}; - -static int rtnl_rtrealm_init; - -static void rtnl_rtrealm_initialize(void) -{ - rtnl_rtrealm_init = 1; - rtnl_tab_initialize("/etc/iproute2/rt_realms", - rtnl_rtrealm_tab, 256); -} - -char * rtnl_rtrealm_n2a(int id, char *buf, int len) -{ - if (id<0 || id>=256) { - snprintf(buf, len, "%d", id); - return buf; - } - if (!rtnl_rtrealm_tab[id]) { - if (!rtnl_rtrealm_init) - rtnl_rtrealm_initialize(); - } - if (rtnl_rtrealm_tab[id]) - return rtnl_rtrealm_tab[id]; - snprintf(buf, len, "%d", id); - return buf; -} - - -int rtnl_rtrealm_a2n(__u32 *id, char *arg) -{ - static char *cache = NULL; - static unsigned long res; - char *end; - int i; - - if (cache && strcmp(cache, arg) == 0) { - *id = res; - return 0; - } - - if (!rtnl_rtrealm_init) - rtnl_rtrealm_initialize(); - - for (i=0; i<256; i++) { - if (rtnl_rtrealm_tab[i] && - strcmp(rtnl_rtrealm_tab[i], arg) == 0) { - cache = rtnl_rtrealm_tab[i]; - res = i; - *id = res; - return 0; - } - } - - res = strtoul(arg, &end, 0); - if (!end || end == arg || *end || res > 255) - return -1; - *id = res; - return 0; -} - - - -static char * rtnl_rttable_tab[256] = { - "unspec", -}; - -static int rtnl_rttable_init; - -static void rtnl_rttable_initialize(void) -{ - rtnl_rttable_init = 1; - rtnl_rttable_tab[255] = "local"; - rtnl_rttable_tab[254] = "main"; - rtnl_rttable_tab[253] = "default"; - rtnl_tab_initialize("/etc/iproute2/rt_tables", - rtnl_rttable_tab, 256); -} - -char * rtnl_rttable_n2a(int id, char *buf, int len) -{ - if (id<0 || id>=256) { - snprintf(buf, len, "%d", id); - return buf; - } - if (!rtnl_rttable_tab[id]) { - if (!rtnl_rttable_init) - rtnl_rttable_initialize(); - } - if (rtnl_rttable_tab[id]) - return rtnl_rttable_tab[id]; - snprintf(buf, len, "%d", id); - return buf; -} - -int rtnl_rttable_a2n(__u32 *id, char *arg) -{ - static char *cache = NULL; - static unsigned long res; - char *end; - int i; - - if (cache && strcmp(cache, arg) == 0) { - *id = res; - return 0; - } - - if (!rtnl_rttable_init) - rtnl_rttable_initialize(); - - for (i=0; i<256; i++) { - if (rtnl_rttable_tab[i] && - strcmp(rtnl_rttable_tab[i], arg) == 0) { - cache = rtnl_rttable_tab[i]; - res = i; - *id = res; - return 0; - } - } - - i = strtoul(arg, &end, 0); - if (!end || end == arg || *end || i > 255) - return -1; - *id = i; - return 0; -} - - -static char * rtnl_rtdsfield_tab[256] = { - "0", -}; - -static int rtnl_rtdsfield_init; - -static void rtnl_rtdsfield_initialize(void) -{ - rtnl_rtdsfield_init = 1; - rtnl_tab_initialize("/etc/iproute2/rt_dsfield", - rtnl_rtdsfield_tab, 256); -} - -char * rtnl_dsfield_n2a(int id, char *buf, int len) -{ - if (id<0 || id>=256) { - snprintf(buf, len, "%d", id); - return buf; - } - if (!rtnl_rtdsfield_tab[id]) { - if (!rtnl_rtdsfield_init) - rtnl_rtdsfield_initialize(); - } - if (rtnl_rtdsfield_tab[id]) - return rtnl_rtdsfield_tab[id]; - snprintf(buf, len, "0x%02x", id); - return buf; -} - - -int rtnl_dsfield_a2n(__u32 *id, char *arg) -{ - static char *cache = NULL; - static unsigned long res; - char *end; - int i; - - if (cache && strcmp(cache, arg) == 0) { - *id = res; - return 0; - } - - if (!rtnl_rtdsfield_init) - rtnl_rtdsfield_initialize(); - - for (i=0; i<256; i++) { - if (rtnl_rtdsfield_tab[i] && - strcmp(rtnl_rtdsfield_tab[i], arg) == 0) { - cache = rtnl_rtdsfield_tab[i]; - res = i; - *id = res; - return 0; - } - } - - res = strtoul(arg, &end, 16); - if (!end || end == arg || *end || res > 255) - return -1; - *id = res; - return 0; -} - diff --git a/lib/utils.c b/lib/utils.c deleted file mode 100644 index 4bdda71..0000000 --- a/lib/utils.c +++ /dev/null @@ -1,640 +0,0 @@ -/* - * utils.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - * - * Changes: - * - * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <string.h> -#include <netdb.h> -#include <arpa/inet.h> -#include <resolv.h> -#include <asm/types.h> -#include <linux/pkt_sched.h> -#include <time.h> -#include <sys/time.h> - - -#include "utils.h" - -int get_integer(int *val, const char *arg, int base) -{ - long res; - char *ptr; - - if (!arg || !*arg) - return -1; - res = strtol(arg, &ptr, base); - if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN) - return -1; - *val = res; - return 0; -} - -int get_unsigned(unsigned *val, const char *arg, int base) -{ - unsigned long res; - char *ptr; - - if (!arg || !*arg) - return -1; - res = strtoul(arg, &ptr, base); - if (!ptr || ptr == arg || *ptr || res > UINT_MAX) - return -1; - *val = res; - return 0; -} - -int get_u64(__u64 *val, const char *arg, int base) -{ - unsigned long long res; - char *ptr; - - if (!arg || !*arg) - return -1; - res = strtoull(arg, &ptr, base); - if (!ptr || ptr == arg || *ptr || res == 0xFFFFFFFFULL) - return -1; - *val = res; - return 0; -} - -int get_u32(__u32 *val, const char *arg, int base) -{ - unsigned long res; - char *ptr; - - if (!arg || !*arg) - return -1; - res = strtoul(arg, &ptr, base); - if (!ptr || ptr == arg || *ptr || res > 0xFFFFFFFFUL) - return -1; - *val = res; - return 0; -} - -int get_u16(__u16 *val, const char *arg, int base) -{ - unsigned long res; - char *ptr; - - if (!arg || !*arg) - return -1; - res = strtoul(arg, &ptr, base); - if (!ptr || ptr == arg || *ptr || res > 0xFFFF) - return -1; - *val = res; - return 0; -} - -int get_u8(__u8 *val, const char *arg, int base) -{ - unsigned long res; - char *ptr; - - if (!arg || !*arg) - return -1; - res = strtoul(arg, &ptr, base); - if (!ptr || ptr == arg || *ptr || res > 0xFF) - return -1; - *val = res; - return 0; -} - -int get_s16(__s16 *val, const char *arg, int base) -{ - long res; - char *ptr; - - if (!arg || !*arg) - return -1; - res = strtol(arg, &ptr, base); - if (!ptr || ptr == arg || *ptr || res > 0x7FFF || res < -0x8000) - return -1; - *val = res; - return 0; -} - -int get_s8(__s8 *val, const char *arg, int base) -{ - long res; - char *ptr; - - if (!arg || !*arg) - return -1; - res = strtol(arg, &ptr, base); - if (!ptr || ptr == arg || *ptr || res > 0x7F || res < -0x80) - return -1; - *val = res; - return 0; -} - -int get_addr_1(inet_prefix *addr, const char *name, int family) -{ - const char *cp; - unsigned char *ap = (unsigned char*)addr->data; - int i; - - memset(addr, 0, sizeof(*addr)); - - if (strcmp(name, "default") == 0 || - strcmp(name, "all") == 0 || - strcmp(name, "any") == 0) { - if (family == AF_DECnet) - return -1; - addr->family = family; - addr->bytelen = (family == AF_INET6 ? 16 : 4); - addr->bitlen = -1; - return 0; - } - - if (strchr(name, ':')) { - addr->family = AF_INET6; - if (family != AF_UNSPEC && family != AF_INET6) - return -1; - if (inet_pton(AF_INET6, name, addr->data) <= 0) - return -1; - addr->bytelen = 16; - addr->bitlen = -1; - return 0; - } - - if (family == AF_DECnet) { - struct dn_naddr dna; - addr->family = AF_DECnet; - if (dnet_pton(AF_DECnet, name, &dna) <= 0) - return -1; - memcpy(addr->data, dna.a_addr, 2); - addr->bytelen = 2; - addr->bitlen = -1; - return 0; - } - - addr->family = AF_INET; - if (family != AF_UNSPEC && family != AF_INET) - return -1; - addr->bytelen = 4; - addr->bitlen = -1; - for (cp=name, i=0; *cp; cp++) { - if (*cp <= '9' && *cp >= '0') { - ap[i] = 10*ap[i] + (*cp-'0'); - continue; - } - if (*cp == '.' && ++i <= 3) - continue; - return -1; - } - return 0; -} - -int get_prefix_1(inet_prefix *dst, char *arg, int family) -{ - int err; - unsigned plen; - char *slash; - - memset(dst, 0, sizeof(*dst)); - - if (strcmp(arg, "default") == 0 || - strcmp(arg, "any") == 0 || - strcmp(arg, "all") == 0) { - if (family == AF_DECnet) - return -1; - dst->family = family; - dst->bytelen = 0; - dst->bitlen = 0; - return 0; - } - - slash = strchr(arg, '/'); - if (slash) - *slash = 0; - - err = get_addr_1(dst, arg, family); - if (err == 0) { - switch(dst->family) { - case AF_INET6: - dst->bitlen = 128; - break; - case AF_DECnet: - dst->bitlen = 16; - break; - default: - case AF_INET: - dst->bitlen = 32; - } - if (slash) { - if (get_unsigned(&plen, slash+1, 0) || plen > dst->bitlen) { - err = -1; - goto done; - } - dst->flags |= PREFIXLEN_SPECIFIED; - dst->bitlen = plen; - } - } -done: - if (slash) - *slash = '/'; - return err; -} - -int get_addr(inet_prefix *dst, const char *arg, int family) -{ - if (family == AF_PACKET) { - fprintf(stderr, "Error: \"%s\" may be inet address, but it is not allowed in this context.\n", arg); - exit(1); - } - if (get_addr_1(dst, arg, family)) { - fprintf(stderr, "Error: an inet address is expected rather than \"%s\".\n", arg); - exit(1); - } - return 0; -} - -int get_prefix(inet_prefix *dst, char *arg, int family) -{ - if (family == AF_PACKET) { - fprintf(stderr, "Error: \"%s\" may be inet prefix, but it is not allowed in this context.\n", arg); - exit(1); - } - if (get_prefix_1(dst, arg, family)) { - fprintf(stderr, "Error: an inet prefix is expected rather than \"%s\".\n", arg); - exit(1); - } - return 0; -} - -__u32 get_addr32(const char *name) -{ - inet_prefix addr; - if (get_addr_1(&addr, name, AF_INET)) { - fprintf(stderr, "Error: an IP address is expected rather than \"%s\"\n", name); - exit(1); - } - return addr.data[0]; -} - -void incomplete_command(void) -{ - fprintf(stderr, "Command line is not complete. Try option \"help\"\n"); - exit(-1); -} - -void missarg(const char *key) -{ - fprintf(stderr, "Error: argument \"%s\" is required\n", key); - exit(-1); -} - -void invarg(const char *msg, const char *arg) -{ - fprintf(stderr, "Error: argument \"%s\" is wrong: %s\n", arg, msg); - exit(-1); -} - -void duparg(const char *key, const char *arg) -{ - fprintf(stderr, "Error: duplicate \"%s\": \"%s\" is the second value.\n", key, arg); - exit(-1); -} - -void duparg2(const char *key, const char *arg) -{ - fprintf(stderr, "Error: either \"%s\" is duplicate, or \"%s\" is a garbage.\n", key, arg); - exit(-1); -} - -int matches(const char *cmd, const char *pattern) -{ - int len = strlen(cmd); - if (len > strlen(pattern)) - return -1; - return memcmp(pattern, cmd, len); -} - -int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits) -{ - __u32 *a1 = a->data; - __u32 *a2 = b->data; - int words = bits >> 0x05; - - bits &= 0x1f; - - if (words) - if (memcmp(a1, a2, words << 2)) - return -1; - - if (bits) { - __u32 w1, w2; - __u32 mask; - - w1 = a1[words]; - w2 = a2[words]; - - mask = htonl((0xffffffff) << (0x20 - bits)); - - if ((w1 ^ w2) & mask) - return 1; - } - - return 0; -} - -int __iproute2_hz_internal; - -int __get_hz(void) -{ - char name[1024]; - int hz = 0; - FILE *fp; - - if (getenv("HZ")) - return atoi(getenv("HZ")) ? : HZ; - - if (getenv("PROC_NET_PSCHED")) { - snprintf(name, sizeof(name)-1, "%s", getenv("PROC_NET_PSCHED")); - } else if (getenv("PROC_ROOT")) { - snprintf(name, sizeof(name)-1, "%s/net/psched", getenv("PROC_ROOT")); - } else { - strcpy(name, "/proc/net/psched"); - } - fp = fopen(name, "r"); - - if (fp) { - unsigned nom, denom; - if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2) - if (nom == 1000000) - hz = denom; - fclose(fp); - } - if (hz) - return hz; - return HZ; -} - -int __iproute2_user_hz_internal; - -int __get_user_hz(void) -{ - return sysconf(_SC_CLK_TCK); -} - -const char *rt_addr_n2a(int af, int len, const void *addr, char *buf, int buflen) -{ - switch (af) { - case AF_INET: - case AF_INET6: - return inet_ntop(af, addr, buf, buflen); - case AF_IPX: - return ipx_ntop(af, addr, buf, buflen); - case AF_DECnet: - { - struct dn_naddr dna = { 2, { 0, 0, }}; - memcpy(dna.a_addr, addr, 2); - return dnet_ntop(af, &dna, buf, buflen); - } - default: - return "???"; - } -} - -#ifdef RESOLVE_HOSTNAMES -struct namerec -{ - struct namerec *next; - inet_prefix addr; - char *name; -}; - -static struct namerec *nht[256]; - -char *resolve_address(const char *addr, int len, int af) -{ - struct namerec *n; - struct hostent *h_ent; - unsigned hash; - static int notfirst; - - - if (af == AF_INET6 && ((__u32*)addr)[0] == 0 && - ((__u32*)addr)[1] == 0 && ((__u32*)addr)[2] == htonl(0xffff)) { - af = AF_INET; - addr += 12; - len = 4; - } - - hash = addr[len-1] ^ addr[len-2] ^ addr[len-3] ^ addr[len-4]; - - for (n = nht[hash]; n; n = n->next) { - if (n->addr.family == af && - n->addr.bytelen == len && - memcmp(n->addr.data, addr, len) == 0) - return n->name; - } - if ((n = malloc(sizeof(*n))) == NULL) - return NULL; - n->addr.family = af; - n->addr.bytelen = len; - n->name = NULL; - memcpy(n->addr.data, addr, len); - n->next = nht[hash]; - nht[hash] = n; - if (++notfirst == 1) - sethostent(1); - fflush(stdout); - - if ((h_ent = gethostbyaddr(addr, len, af)) != NULL) - n->name = strdup(h_ent->h_name); - - /* Even if we fail, "negative" entry is remembered. */ - return n->name; -} -#endif - - -const char *format_host(int af, int len, const void *addr, - char *buf, int buflen) -{ -#ifdef RESOLVE_HOSTNAMES - if (resolve_hosts) { - char *n; - if (len <= 0) { - switch (af) { - case AF_INET: - len = 4; - break; - case AF_INET6: - len = 16; - break; - case AF_IPX: - len = 10; - break; -#ifdef AF_DECnet - /* I see no reasons why gethostbyname - may not work for DECnet */ - case AF_DECnet: - len = 2; - break; -#endif - default: ; - } - } - if (len > 0 && - (n = resolve_address(addr, len, af)) != NULL) - return n; - } -#endif - return rt_addr_n2a(af, len, addr, buf, buflen); -} - - -char *hexstring_n2a(const __u8 *str, int len, char *buf, int blen) -{ - char *ptr = buf; - int i; - - for (i=0; i<len; i++) { - if (blen < 3) - break; - sprintf(ptr, "%02x", str[i]); - ptr += 2; - blen -= 2; - if (i != len-1 && blen > 1) { - *ptr++ = ':'; - blen--; - } - } - return buf; -} - -__u8* hexstring_a2n(const char *str, __u8 *buf, int blen) -{ - int cnt = 0; - - for (;;) { - unsigned acc; - char ch; - - acc = 0; - - while ((ch = *str) != ':' && ch != 0) { - if (ch >= '0' && ch <= '9') - ch -= '0'; - else if (ch >= 'a' && ch <= 'f') - ch -= 'a'-10; - else if (ch >= 'A' && ch <= 'F') - ch -= 'A'-10; - else - return NULL; - acc = (acc<<4) + ch; - str++; - } - - if (acc > 255) - return NULL; - if (cnt < blen) { - buf[cnt] = acc; - cnt++; - } - if (ch == 0) - break; - ++str; - } - if (cnt < blen) - memset(buf+cnt, 0, blen-cnt); - return buf; -} - -int print_timestamp(FILE *fp) -{ - struct timeval tv; - char *tstr; - - memset(&tv, 0, sizeof(tv)); - gettimeofday(&tv, NULL); - - tstr = asctime(localtime(&tv.tv_sec)); - tstr[strlen(tstr)-1] = 0; - fprintf(fp, "Timestamp: %s %lu usec\n", tstr, tv.tv_usec); - return 0; -} - -int cmdlineno; - -/* Like glibc getline but handle continuation lines and comments */ -size_t getcmdline(char **linep, size_t *lenp, FILE *in) -{ - size_t cc; - char *cp; - - if ((cc = getline(linep, lenp, in)) < 0) - return cc; /* eof or error */ - ++cmdlineno; - - cp = strchr(*linep, '#'); - if (cp) - *cp = '\0'; - - while ((cp = strstr(*linep, "\\\n")) != NULL) { - char *line1 = NULL; - size_t len1 = 0; - size_t cc1; - - if ((cc1 = getline(&line1, &len1, in)) < 0) { - fprintf(stderr, "Missing continuation line\n"); - return cc1; - } - - ++cmdlineno; - *cp = 0; - - cp = strchr(line1, '#'); - if (cp) - *cp = '\0'; - - *linep = realloc(*linep, strlen(*linep) + strlen(line1) + 1); - if (!*linep) { - fprintf(stderr, "Out of memory\n"); - return -1; - } - cc += cc1 - 2; - strcat(*linep, line1); - free(line1); - } - return cc; -} - -/* split command line into argument vector */ -int makeargs(char *line, char *argv[], int maxargs) -{ - static const char ws[] = " \t\r\n"; - char *cp; - int argc = 0; - - for (cp = strtok(line, ws); cp; cp = strtok(NULL, ws)) { - if (argc >= (maxargs - 1)) { - fprintf(stderr, "Too many arguments to command\n"); - exit(1); - } - argv[argc++] = cp; - } - argv[argc] = NULL; - - return argc; -} diff --git a/man/man3/libnetlink.3 b/man/man3/libnetlink.3 deleted file mode 100644 index 145f38d..0000000 --- a/man/man3/libnetlink.3 +++ /dev/null @@ -1,197 +0,0 @@ -.TH libnetlink 3 -.SH NAME -libnetlink \- A library for accessing the netlink service -.SH SYNOPSIS -.nf -#include <asm/types.h> -.br -#include <libnetlink.h> -.br -#include <linux/netlink.h> -.br -#include <linux/rtnetlink.h> -.sp -int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions) -.sp -int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) -.sp -int rtnl_send(struct rtnl_handle *rth, char *buf, int len) -.sp -int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) -.sp -int rtnl_dump_filter(struct rtnl_handle *rth, - int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *), - void *arg1, - int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *), - void *arg2) -.sp -int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, - unsigned groups, struct nlmsghdr *answer, -.br - int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *), -.br - void *jarg) -.sp -int rtnl_listen(struct rtnl_handle *rtnl, - int (*handler)(struct sockaddr_nl *,struct nlmsghdr *n, void *), - void *jarg) -.sp -int rtnl_from_file(FILE *rtnl, - int (*handler)(struct sockaddr_nl *,struct nlmsghdr *n, void *), - void *jarg) -.sp -int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data) -.sp -int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen) -.sp -int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data) -.sp -int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen) -.SH DESCRIPTION -libnetlink provides a higher level interface to -.BR rtnetlink(7). -The read functions return 0 on success and a negative errno on failure. -The send functions return the amount of data sent, or -1 on error. -.TP -rtnl_open -Open a rtnetlink socket and save the state into the -.B rth -handle. This handle is passed to all subsequent calls. -.B subscriptions -is a bitmap of the rtnetlink multicast groups the socket will be -a member of. - -.TP -rtnl_wilddump_request -Request a full dump of the -.B type -database for -.B family -addresses. -.B type -is a rtnetlink message type. -.\" XXX - -.TP -rtnl_dump_request -Request a full dump of the -.B type -data buffer into -.B buf -with maximum length of -.B len. -.B type -is a rtnetlink message type. - -.TP -rtnl_dump_filter -Receive netlink data after a request and filter it. -The -.B filter -callback checks if the received message is wanted. It gets the source -address of the message, the message itself and -.B arg1 -as arguments. 0 as return means that the filter passed, a negative -value is returned -by -.I rtnl_dump_filter -in case of error. NULL for -.I filter -means to not use a filter. -.B junk -is used to filter messages not destined to the local socket. -Only one message bundle is received. Unless there is no message -pending, this function does not block. - -.TP -rtnl_listen -Receive netlink data after a request and pass it to -.I handler. -.B handler -is a callback that gets the message source address, the message itself, -and the -.B jarg -cookie as arguments. It will get called for all received messages. -Only one message bundle is received. Unless there is no message -pending this function does not block. - -.TP -rtnl_from_file -Works like -.I rtnl_listen, -but reads a netlink message bundle from the file -.B file -and passes the messages to -.B handler -for parsing. The file contains raw data as received from a rtnetlink socket. -.PP -The following functions are useful to construct custom rtnetlink messages. For -simple database dumping with filtering it is better to use the higher level -functions above. See -.BR rtnetlink(3) -and -.BR netlink(3) -on how to generate a rtnetlink message. The following utility functions -require a continuous buffer that already contains a netlink message header -and a rtnetlink request. - -.TP -rtnl_send -Send the rtnetlink message in -.B buf -of length -.B len -to handle -.B rth. - -.TP -addattr32 -Add a __u32 attribute of type -.B type -and with value -.B data -to netlink message -.B n, -which is part of a buffer of length -.B maxlen. - -.TP -addattr_l -Add a variable length attribute of type -.B type -and with value -.B data -and -.B alen -length to netlink message -.B n, -which is part of a buffer of length -.B maxlen. -.B data -is copied. - -.TP -rta_addattr32 -Initialize the rtnetlink attribute -.B rta -with a __u32 data value. - -.TP -rta_addattr32 -Initialize the rtnetlink attribute -.B rta -with a variable length data value. - -.SH BUGS -The functions sometimes use fprintf and exit when a fatal error occurs. -This library should be named librtnetlink. - -.SH AUTHORS -netlink/rtnetlink was designed and writen by Alexey Kuznetsov. -Andi Kleen wrote the man page. - -.SH SEE ALSO -.BR netlink(7), -.BR rtnetlink(7) -.br -/usr/include/linux/rtnetlink.h diff --git a/man/man8/ip.8 b/man/man8/ip.8 deleted file mode 100644 index 12da6d5..0000000 --- a/man/man8/ip.8 +++ /dev/null @@ -1,1813 +0,0 @@ -.TH IP 8 "17 January 2002" "iproute2" "Linux" -.SH NAME -ip \- show / manipulate routing, devices, policy routing and tunnels -.SH SYNOPSIS - -.ad l -.in +8 -.ti -8 -.B ip -.RI "[ " OPTIONS " ] " OBJECT " { " COMMAND " | " -.BR help " }" -.sp - -.ti -8 -.IR OBJECT " := { " -.BR link " | " addr " | " route " | " rule " | " neigh " | " tunnel " | "\ -maddr " | " mroute " | " monitor " }" -.sp - -.ti -8 -.IR OPTIONS " := { " -\fB\-V\fR[\fIersion\fR] | -\fB\-s\fR[\fItatistics\fR] | -\fB\-r\fR[\fIesolve\fR] | -\fB\-f\fR[\fIamily\fR] { -.BR inet " | " inet6 " | " ipx " | " dnet " | " link " } | " -\fB\-o\fR[\fIneline\fR] } - -.ti -8 -.BI "ip link set " DEVICE -.RB "{ " up " | " down " | " arp " { " on " | " off " } |" -.br -.BR promisc " { " on " | " off " } |" -.br -.BR allmulti " { " on " | " off " } |" -.br -.BR dynamic " { " on " | " off " } |" -.br -.BR multicast " { " on " | " off " } |" -.br -.B txqueuelen -.IR PACKETS " |" -.br -.B name -.IR NEWNAME " |" -.br -.B address -.IR LLADDR " |" -.B broadcast -.IR LLADDR " |" -.br -.B mtu -.IR MTU " }" - -.ti -8 -.B ip link show -.RI "[ " DEVICE " ]" - -.ti -8 -.BR "ip addr" " { " add " | " del " } " -.IB IFADDR " dev " STRING - -.ti -8 -.BR "ip addr" " { " show " | " flush " } [ " dev -.IR STRING " ] [ " -.B scope -.IR SCOPE-ID " ] [ " -.B to -.IR PREFIX " ] [ " FLAG-LIST " ] [ " -.B label -.IR PATTERN " ]" - -.ti -8 -.IR IFADDR " := " PREFIX " | " ADDR -.B peer -.IR PREFIX " [ " -.B broadcast -.IR ADDR " ] [ " -.B anycast -.IR ADDR " ] [ " -.B label -.IR STRING " ] [ " -.B scope -.IR SCOPE-ID " ]" - -.ti -8 -.IR SCOPE-ID " := " -.RB "[ " host " | " link " | " global " | " -.IR NUMBER " ]" - -.ti -8 -.IR FLAG-LIST " := [ " FLAG-LIST " ] " FLAG - -.ti -8 -.IR FLAG " := " -.RB "[ " permanent " | " dynamic " | " secondary " | " primary " | "\ -tentative " | " deprecated " ]" - -.ti -8 -.BR "ip route" " { " -.BR list " | " flush " } " -.I SELECTOR - -.ti -8 -.B ip route get -.IR ADDRESS " [ " -.BI from " ADDRESS " iif " STRING" -.RB " ] [ " oif -.IR STRING " ] [ " -.B tos -.IR TOS " ]" - -.ti -8 -.BR "ip route" " { " add " | " del " | " change " | " append " | "\ -replace " | " monitor " } " -.I ROUTE - -.ti -8 -.IR SELECTOR " := " -.RB "[ " root -.IR PREFIX " ] [ " -.B match -.IR PREFIX " ] [ " -.B exact -.IR PREFIX " ] [ " -.B table -.IR TABLE_ID " ] [ " -.B proto -.IR RTPROTO " ] [ " -.B type -.IR TYPE " ] [ " -.B scope -.IR SCOPE " ]" - -.ti -8 -.IR ROUTE " := " NODE_SPEC " [ " INFO_SPEC " ]" - -.ti -8 -.IR NODE_SPEC " := [ " TYPE " ] " PREFIX " [" -.B tos -.IR TOS " ] [ " -.B table -.IR TABLE_ID " ] [ " -.B proto -.IR RTPROTO " ] [ " -.B scope -.IR SCOPE " ] [ " -.B metric -.IR METRIC " ]" - -.ti -8 -.IR INFO_SPEC " := " "NH OPTIONS FLAGS" " [" -.B nexthop -.IR NH " ] ..." - -.ti -8 -.IR NH " := [ " -.B via -.IR ADDRESS " ] [ " -.B dev -.IR STRING " ] [ " -.B weight -.IR NUMBER " ] " NHFLAGS - -.ti -8 -.IR OPTIONS " := " FLAGS " [ " -.B mtu -.IR NUMBER " ] [ " -.B advmss -.IR NUMBER " ] [ " -.B rtt -.IR NUMBER " ] [ " -.B rttvar -.IR NUMBER " ] [ " -.B window -.IR NUMBER " ] [ " -.B cwnd -.IR NUMBER " ] [ " -.B ssthresh -.IR REALM " ] [ " -.B realms -.IR REALM " ]" - -.ti -8 -.IR TYPE " := [ " -.BR unicast " | " local " | " broadcast " | " multicast " | "\ -throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]" - -.ti -8 -.IR TABLE_ID " := [ " -.BR local "| " main " | " default " | " all " |" -.IR NUMBER " ]" - -.ti -8 -.IR SCOPE " := [ " -.BR host " | " link " | " global " |" -.IR NUMBER " ]" - -.ti -8 -.IR FLAGS " := [ " -.BR equalize " ]" - -.ti -8 -.IR NHFLAGS " := [ " -.BR onlink " | " pervasive " ]" - -.ti -8 -.IR RTPROTO " := [ " -.BR kernel " | " boot " | " static " |" -.IR NUMBER " ]" - -.ti -8 -.B ip rule -.RB " [ " list " | " add " | " del " | " flush " ]" -.I SELECTOR ACTION - -.ti -8 -.IR SELECTOR " := [ " -.B from -.IR PREFIX " ] [ " -.B to -.IR PREFIX " ] [ " -.B tos -.IR TOS " ] [ " -.B fwmark -.IR FWMARK " ] [ " -.B dev -.IR STRING " ] [ " -.B pref -.IR NUMBER " ]" - -.ti -8 -.IR ACTION " := [ " -.B table -.IR TABLE_ID " ] [ " -.B nat -.IR ADDRESS " ] [ " -.BR prohibit " | " reject " | " unreachable " ] [ " realms -.RI "[" SRCREALM "/]" DSTREALM " ]" - -.ti -8 -.IR TABLE_ID " := [ " -.BR local " | " main " | " default " |" -.IR NUMBER " ]" - -.ti -8 -.BR "ip neigh" " { " add " | " del " | " change " | " replace " } { " -.IR ADDR " [ " -.B lladdr -.IR LLADDR " ] [ " -.BR nud " { " permanent " | " noarp " | " stale " | " reachable " } ] | " proxy -.IR ADDR " } [ " -.B dev -.IR DEV " ]" - -.ti -8 -.BR "ip neigh" " { " show " | " flush " } [ " to -.IR PREFIX " ] [ " -.B dev -.IR DEV " ] [ " -.B nud -.IR STATE " ]" - -.ti -8 -.BR "ip tunnel" " { " add " | " change " | " del " | " show " }" -.RI "[ " NAME " ]" -.br -.RB "[ " mode " { " ipip " | " gre " | " sit " } ]" -.br -.RB "[ " remote -.IR ADDR " ] [ " -.B local -.IR ADDR " ]" -.br -.RB "[ [" i "|" o "]" seq " ] [ [" i "|" o "]" key -.IR KEY " ] [ " -.RB "[" i "|" o "]" csum " ] ]" -.br -.RB "[ " ttl -.IR TTL " ] [ " -.B tos -.IR TOS " ] [ " -.RB "[" no "]" pmtudisc " ]" -.br -.RB "[ " dev -.IR PHYS_DEV " ]" - -.ti -8 -.IR ADDR " := { " IP_ADDRESS " |" -.BR any " }" - -.ti -8 -.IR TOS " := { " NUMBER " |" -.BR inherit " }" - -.ti -8 -.IR TTL " := { " 1 ".." 255 " | " -.BR inherit " }" - -.ti -8 -.IR KEY " := { " DOTTED_QUAD " | " NUMBER " }" - -.ti -8 -.BR "ip maddr" " [ " add " | " del " ]" -.IB MULTIADDR " dev " STRING - -.ti -8 -.BR "ip maddr show" " [ " dev -.IR STRING " ]" - -.ti -8 -.BR "ip mroute show" " [" -.IR PREFIX " ] [ " -.B from -.IR PREFIX " ] [ " -.B iif -.IR DEVICE " ]" - -.ti -8 -.BR "ip monitor" " [ " all " |" -.IR LISTofOBJECTS " ]" -.in -8 -.ad b - -.SH OPTIONS - -.TP -.BR "\-V" , " -Version" -print the version of the -.B ip -utility and exit. - -.TP -.BR "\-s" , " \-stats", " \-statistics" -output more information. If the option -appears twice or more, the amount of information increases. -As a rule, the information is statistics or some time values. - -.TP -.BR "\-f" , " \-family" -followed by protocol family identifier: -.BR "inet" , " inet6" -or -.B link -,enforce the protocol family to use. If the option is not present, -the protocol family is guessed from other arguments. If the rest -of the command line does not give enough information to guess the -family, -.B ip -falls back to the default one, usually -.B inet -or -.BR "any" . -.B link -is a special family identifier meaning that no networking protocol -is involved. - -.TP -.B \-4 -shortcut for -.BR "-family inet" . - -.TP -.B \-6 -shortcut for -.BR "\-family inet6" . - -.TP -.B \-0 -shortcut for -.BR "\-family link" . - -.TP -.BR "\-o" , " \-oneline" -output each record on a single line, replacing line feeds -with the -.B '\' -character. This is convenient when you want to count records -with -.BR wc (1) - or to -.BR grep (1) -the output. - -.TP -.BR "\-r" , " \-resolve" -use the system's name resolver to print DNS names instead of -host addresses. - -.SH IP - COMMAND SYNTAX - -.SS -.I OBJECT - -.TP -.B link -- network device. - -.TP -.B address -- protocol (IP or IPv6) address on a device. -.TP -.B neighbour -- ARP or NDISC cache entry. - -.TP -.B route -- routing table entry. - -.TP -.B rule -- rule in routing policy database. - -.TP -.B maddress -- multicast address. - -.TP -.B mroute -- multicast routing cache entry. - -.TP -.B tunnel -- tunnel over IP. - -.PP -The names of all objects may be written in full or -abbreviated form, f.e. -.B address -is abbreviated as -.B addr -or just -.B a. - -.SS -.I COMMAND - -Specifies the action to perform on the object. -The set of possible actions depends on the object type. -As a rule, it is possible to -.BR "add" , " delete" -and -.B show -(or -.B list -) objects, but some objects do not allow all of these operations -or have some additional commands. The -.B help -command is available for all objects. It prints -out a list of available commands and argument syntax conventions. -.sp -If no command is given, some default command is assumed. -Usually it is -.B list -or, if the objects of this class cannot be listed, -.BR "help" . - -.SH ip link - network device configuration - -.B link -is a network device and the corresponding commands -display and change the state of devices. - -.SS ip link set - change device attributes - -.TP -.BI dev " NAME " (default) -.I NAME -specifies network device to operate on. - -.TP -.BR up " and " down -change the state of the device to -.B UP -or -.BR "DOWN" . - -.TP -.BR "arp on " or " arp off" -change the -.B NOARP -flag on the device. - -.TP -.BR "multicast on " or " multicast off" -change the -.B MULTICAST -flag on the device. - -.TP -.BR "dynamic on " or " dynamic off" -change the -.B DYNAMIC -flag on the device. - -.TP -.BI name " NAME" -change the name of the device. This operation is not -recommended if the device is running or has some addresses -already configured. - -.TP -.BI txqueuelen " NUMBER" -.TP -.BI txqlen " NUMBER" -change the transmit queue length of the device. - -.TP -.BI mtu " NUMBER" -change the -.I MTU -of the device. - -.TP -.BI address " LLADDRESS" -change the station address of the interface. - -.TP -.BI broadcast " LLADDRESS" -.TP -.BI brd " LLADDRESS" -.TP -.BI peer " LLADDRESS" -change the link layer broadcast address or the peer address when -the interface is -.IR "POINTOPOINT" . - -.PP -.B Warning: -If multiple parameter changes are requested, -.B ip -aborts immediately after any of the changes have failed. -This is the only case when -.B ip -can move the system to an unpredictable state. The solution -is to avoid changing several parameters with one -.B ip link set -call. - -.SS ip link show - display device attributes - -.TP -.BI dev " NAME " (default) -.I NAME -specifies the network device to show. -If this argument is omitted all devices are listed. - -.TP -.B up -only display running interfaces. - -.SH ip address - protocol address management. - -The -.B address -is a protocol (IP or IPv6) address attached -to a network device. Each device must have at least one address -to use the corresponding protocol. It is possible to have several -different addresses attached to one device. These addresses are not -discriminated, so that the term -.B alias -is not quite appropriate for them and we do not use it in this document. -.sp -The -.B ip addr -command displays addresses and their properties, adds new addresses -and deletes old ones. - -.SS ip address add - add new protocol address. - -.TP -.BI dev " NAME" -the name of the device to add the address to. - -.TP -.BI local " ADDRESS " (default) -the address of the interface. The format of the address depends -on the protocol. It is a dotted quad for IP and a sequence of -hexadecimal halfwords separated by colons for IPv6. The -.I ADDRESS -may be followed by a slash and a decimal number which encodes -the network prefix length. - -.TP -.BI peer " ADDRESS" -the address of the remote endpoint for pointopoint interfaces. -Again, the -.I ADDRESS -may be followed by a slash and a decimal number, encoding the network -prefix length. If a peer address is specified, the local address -cannot have a prefix length. The network prefix is associated -with the peer rather than with the local address. - -.TP -.BI broadcast " ADDRESS" -the broadcast address on the interface. -.sp -It is possible to use the special symbols -.B '+' -and -.B '-' -instead of the broadcast address. In this case, the broadcast address -is derived by setting/resetting the host bits of the interface prefix. - -.TP -.BI label " NAME" -Each address may be tagged with a label string. -In order to preserve compatibility with Linux-2.0 net aliases, -this string must coincide with the name of the device or must be prefixed -with the device name followed by colon. - -.TP -.BI scope " SCOPE_VALUE" -the scope of the area where this address is valid. -The available scopes are listed in file -.BR "/etc/iproute2/rt_scopes" . -Predefined scope values are: - -.in +8 -.B global -- the address is globally valid. -.sp -.B site -- (IPv6 only) the address is site local, i.e. it is -valid inside this site. -.sp -.B link -- the address is link local, i.e. it is valid only on this device. -.sp -.B host -- the address is valid only inside this host. -.in -8 - -.SS ip address delete - delete protocol address -.B Arguments: -coincide with the arguments of -.B ip addr add. -The device name is a required argument. The rest are optional. -If no arguments are given, the first address is deleted. - -.SS ip address show - look at protocol addresses - -.TP -.BI dev " NAME " (default) -name of device. - -.TP -.BI scope " SCOPE_VAL" -only list addresses with this scope. - -.TP -.BI to " PREFIX" -only list addresses matching this prefix. - -.TP -.BI label " PATTERN" -only list addresses with labels matching the -.IR "PATTERN" . -.I PATTERN -is a usual shell style pattern. - -.TP -.BR dynamic " and " permanent -(IPv6 only) only list addresses installed due to stateless -address configuration or only list permanent (not dynamic) -addresses. - -.TP -.B tentative -(IPv6 only) only list addresses which did not pass duplicate -address detection. - -.TP -.B deprecated -(IPv6 only) only list deprecated addresses. - -.TP -.BR primary " and " secondary -only list primary (or secondary) addresses. - -.SS ip address flush - flush protocol addresses -This command flushes the protocol addresses selected by some criteria. - -.PP -This command has the same arguments as -.B show. -The difference is that it does not run when no arguments are given. - -.PP -.B Warning: -This command (and other -.B flush -commands described below) is pretty dangerous. If you make a mistake, -it will not forgive it, but will cruelly purge all the addresses. - -.PP -With the -.B -statistics -option, the command becomes verbose. It prints out the number of deleted -addresses and the number of rounds made to flush the address list. If -this option is given twice, -.B ip addr flush -also dumps all the deleted addresses in the format described in the -previous subsection. - -.SH ip neighbour - neighbour/arp tables management. - -.B neighbour -objects establish bindings between protocol addresses and -link layer addresses for hosts sharing the same link. -Neighbour entries are organized into tables. The IPv4 neighbour table -is known by another name - the ARP table. - -.P -The corresponding commands display neighbour bindings -and their properties, add new neighbour entries and delete old ones. - -.SS ip neighbour add - add a new neighbour entry -.SS ip neighbour change - change an existing entry -.SS ip neighbour replace - add a new entry or change an existing one - -These commands create new neighbour records or update existing ones. - -.TP -.BI to " ADDRESS " (default) -the protocol address of the neighbour. It is either an IPv4 or IPv6 address. - -.TP -.BI dev " NAME" -the interface to which this neighbour is attached. - -.TP -.BI lladdr " LLADDRESS" -the link layer address of the neighbour. -.I LLADDRESS -can also be -.BR "null" . - -.TP -.BI nud " NUD_STATE" -the state of the neighbour entry. -.B nud -is an abbreviation for 'Neigh bour Unreachability Detection'. -The state can take one of the following values: - -.in +8 -.B permanent -- the neighbour entry is valid forever and can be only -be removed administratively. -.sp - -.B noarp -- the neighbour entry is valid. No attempts to validate -this entry will be made but it can be removed when its lifetime expires. -.sp - -.B reachable -- the neighbour entry is valid until the reachability -timeout expires. -.sp - -.B stale -- the neighbour entry is valid but suspicious. -This option to -.B ip neigh -does not change the neighbour state if it was valid and the address -is not changed by this command. -.in -8 - -.SS ip neighbour delete - delete a neighbour entry -This command invalidates a neighbour entry. - -.PP -The arguments are the same as with -.BR "ip neigh add" , -except that -.B lladdr -and -.B nud -are ignored. - -.PP -.B Warning: -Attempts to delete or manually change a -.B noarp -entry created by the kernel may result in unpredictable behaviour. -Particularly, the kernel may try to resolve this address even -on a -.B NOARP -interface or if the address is multicast or broadcast. - -.SS ip neighbour show - list neighbour entries - -This commands displays neighbour tables. - -.TP -.BI to " ADDRESS " (default) -the prefix selecting the neighbours to list. - -.TP -.BI dev " NAME" -only list the neighbours attached to this device. - -.TP -.B unused -only list neighbours which are not currently in use. - -.TP -.BI nud " NUD_STATE" -only list neighbour entries in this state. -.I NUD_STATE -takes values listed below or the special value -.B all -which means all states. This option may occur more than once. -If this option is absent, -.B ip -lists all entries except for -.B none -and -.BR "noarp" . - -.SS ip neighbour flush - flush neighbour entries -This command flushes neighbour tables, selecting -entries to flush by some criteria. - -.PP -This command has the same arguments as -.B show. -The differences are that it does not run when no arguments are given, -and that the default neighbour states to be flushed do not include -.B permanent -and -.BR "noarp" . - -.PP -With the -.B -statistics -option, the command becomes verbose. It prints out the number of -deleted neighbours and the number of rounds made to flush the -neighbour table. If the option is given -twice, -.B ip neigh flush -also dumps all the deleted neighbours. - -.SH ip route - routing table management -Manipulate route entries in the kernel routing tables keep -information about paths to other networked nodes. -.sp -.B Route types: - -.in +8 -.B unicast -- the route entry describes real paths to the destinations covered -by the route prefix. - -.sp -.B unreachable -- these destinations are unreachable. Packets are discarded and the -ICMP message -.I host unreachable -is generated. -The local senders get an -.I EHOSTUNREACH -error. - -.sp -.B blackhole -- these destinations are unreachable. Packets are discarded silently. -The local senders get an -.I EINVAL -error. - -.sp -.B prohibit -- these destinations are unreachable. Packets are discarded and the -ICMP message -.I communication administratively prohibited -is generated. The local senders get an -.I EACCES -error. - -.sp -.B local -- the destinations are assigned to this host. The packets are looped -back and delivered locally. - -.sp -.B broadcast -- the destinations are broadcast addresses. The packets are sent as -link broadcasts. - -.sp -.B throw -- a special control route used together with policy rules. If such a -route is selected, lookup in this table is terminated pretending that -no route was found. Without policy routing it is equivalent to the -absence of the route in the routing table. The packets are dropped -and the ICMP message -.I net unreachable -is generated. The local senders get an -.I ENETUNREACH -error. - -.sp -.B nat -- a special NAT route. Destinations covered by the prefix -are considered to be dummy (or external) addresses which require translation -to real (or internal) ones before forwarding. The addresses to translate to -are selected with the attribute -.B Warning: -Route NAT is no longer supported in Linux 2.6. - - -.BR "via" . -.sp -.B anycast -.RI "- " "not implemented" -the destinations are -.I anycast -addresses assigned to this host. They are mainly equivalent -to -.B local -with one difference: such addresses are invalid when used -as the source address of any packet. - -.sp -.B multicast -- a special type used for multicast routing. It is not present in -normal routing tables. -.in -8 - -.P -.B Route tables: -Linux-2.x can pack routes into several routing -tables identified by a number in the range from 1 to 255 or by -name from the file -.B /etc/iproute2/rt_tables -. By default all normal routes are inserted into the -.B main -table (ID 254) and the kernel only uses this table when calculating routes. - -.sp -Actually, one other table always exists, which is invisible but -even more important. It is the -.B local -table (ID 255). This table -consists of routes for local and broadcast addresses. The kernel maintains -this table automatically and the administrator usually need not modify it -or even look at it. - -The multiple routing tables enter the game when -.I policy routing -is used. - -.SS ip route add - add new route -.SS ip route change - change route -.SS ip route replace - change or add new one - -.TP -.BI to " TYPE PREFIX " (default) -the destination prefix of the route. If -.I TYPE -is omitted, -.B ip -assumes type -.BR "unicast" . -Other values of -.I TYPE -are listed above. -.I PREFIX -is an IP or IPv6 address optionally followed by a slash and the -prefix length. If the length of the prefix is missing, -.B ip -assumes a full-length host route. There is also a special -.I PREFIX -.B default -- which is equivalent to IP -.B 0/0 -or to IPv6 -.BR "::/0" . - -.TP -.BI tos " TOS" -.TP -.BI dsfield " TOS" -the Type Of Service (TOS) key. This key has no associated mask and -the longest match is understood as: First, compare the TOS -of the route and of the packet. If they are not equal, then the packet -may still match a route with a zero TOS. -.I TOS -is either an 8 bit hexadecimal number or an identifier -from -.BR "/etc/iproute2/rt_dsfield" . - -.TP -.BI metric " NUMBER" -.TP -.BI preference " NUMBER" -the preference value of the route. -.I NUMBER -is an arbitrary 32bit number. - -.TP -.BI table " TABLEID" -the table to add this route to. -.I TABLEID -may be a number or a string from the file -.BR "/etc/iproute2/rt_tables" . -If this parameter is omitted, -.B ip -assumes the -.B main -table, with the exception of -.BR local " , " broadcast " and " nat -routes, which are put into the -.B local -table by default. - -.TP -.BI dev " NAME" -the output device name. - -.TP -.BI via " ADDRESS" -the address of the nexthop router. Actually, the sense of this field -depends on the route type. For normal -.B unicast -routes it is either the true next hop router or, if it is a direct -route installed in BSD compatibility mode, it can be a local address -of the interface. For NAT routes it is the first address of the block -of translated IP destinations. - -.TP -.BI src " ADDRESS" -the source address to prefer when sending to the destinations -covered by the route prefix. - -.TP -.BI realm " REALMID" -the realm to which this route is assigned. -.I REALMID -may be a number or a string from the file -.BR "/etc/iproute2/rt_realms" . - -.TP -.BI mtu " MTU" -.TP -.BI "mtu lock" " MTU" -the MTU along the path to the destination. If the modifier -.B lock -is not used, the MTU may be updated by the kernel due to -Path MTU Discovery. If the modifier -.B lock -is used, no path MTU discovery will be tried, all packets -will be sent without the DF bit in IPv4 case or fragmented -to MTU for IPv6. - -.TP -.BI window " NUMBER" -the maximal window for TCP to advertise to these destinations, -measured in bytes. It limits maximal data bursts that our TCP -peers are allowed to send to us. - -.TP -.BI rtt " NUMBER" -the initial RTT ('Round Trip Time') estimate. - -.TP -.BI rttvar " NUMBER " "(2.3.15+ only)" -the initial RTT variance estimate. - -.TP -.BI ssthresh " NUMBER " "(2.3.15+ only)" -an estimate for the initial slow start threshold. - -.TP -.BI cwnd " NUMBER " "(2.3.15+ only)" -the clamp for congestion window. It is ignored if the -.B lock -flag is not used. - -.TP -.BI advmss " NUMBER " "(2.3.15+ only)" -the MSS ('Maximal Segment Size') to advertise to these -destinations when establishing TCP connections. If it is not given, -Linux uses a default value calculated from the first hop device MTU. -(If the path to these destination is asymmetric, this guess may be wrong.) - -.TP -.BI reordering " NUMBER " "(2.3.15+ only)" -Maximal reordering on the path to this destination. -If it is not given, Linux uses the value selected with -.B sysctl -variable -.BR "net/ipv4/tcp_reordering" . - -.TP -.BI nexthop " NEXTHOP" -the nexthop of a multipath route. -.I NEXTHOP -is a complex value with its own syntax similar to the top level -argument lists: - -.in +8 -.BI via " ADDRESS" -- is the nexthop router. -.sp - -.BI dev " NAME" -- is the output device. -.sp - -.BI weight " NUMBER" -- is a weight for this element of a multipath -route reflecting its relative bandwidth or quality. -.in -8 - -.TP -.BI scope " SCOPE_VAL" -the scope of the destinations covered by the route prefix. -.I SCOPE_VAL -may be a number or a string from the file -.BR "/etc/iproute2/rt_scopes" . -If this parameter is omitted, -.B ip -assumes scope -.B global -for all gatewayed -.B unicast -routes, scope -.B link -for direct -.BR unicast " and " broadcast -routes and scope -.BR host " for " local -routes. - -.TP -.BI protocol " RTPROTO" -the routing protocol identifier of this route. -.I RTPROTO -may be a number or a string from the file -.BR "/etc/iproute2/rt_protos" . -If the routing protocol ID is not given, -.B ip assumes protocol -.B boot -(i.e. it assumes the route was added by someone who doesn't -understand what they are doing). Several protocol values have -a fixed interpretation. -Namely: - -.in +8 -.B redirect -- the route was installed due to an ICMP redirect. -.sp - -.B kernel -- the route was installed by the kernel during autoconfiguration. -.sp - -.B boot -- the route was installed during the bootup sequence. -If a routing daemon starts, it will purge all of them. -.sp - -.B static -- the route was installed by the administrator -to override dynamic routing. Routing daemon will respect them -and, probably, even advertise them to its peers. -.sp - -.B ra -- the route was installed by Router Discovery protocol. -.in -8 - -.sp -The rest of the values are not reserved and the administrator is free -to assign (or not to assign) protocol tags. - -.TP -.B onlink -pretend that the nexthop is directly attached to this link, -even if it does not match any interface prefix. - -.TP -.B equalize -allow packet by packet randomization on multipath routes. -Without this modifier, the route will be frozen to one selected -nexthop, so that load splitting will only occur on per-flow base. -.B equalize -only works if the kernel is patched. - -.SS ip route delete - delete route - -.B ip route del -has the same arguments as -.BR "ip route add" , -but their semantics are a bit different. - -Key values -.RB "(" to ", " tos ", " preference " and " table ")" -select the route to delete. If optional attributes are present, -.B ip -verifies that they coincide with the attributes of the route to delete. -If no route with the given key and attributes was found, -.B ip route del -fails. - -.SS ip route show - list routes -the command displays the contents of the routing tables or the route(s) -selected by some criteria. - -.TP -.BI to " SELECTOR " (default) -only select routes from the given range of destinations. -.I SELECTOR -consists of an optional modifier -.RB "(" root ", " match " or " exact ")" -and a prefix. -.BI root " PREFIX" -selects routes with prefixes not shorter than -.IR PREFIX "." -F.e. -.BI root " 0/0" -selects the entire routing table. -.BI match " PREFIX" -selects routes with prefixes not longer than -.IR PREFIX "." -F.e. -.BI match " 10.0/16" -selects -.IR 10.0/16 "," -.IR 10/8 " and " 0/0 , -but it does not select -.IR 10.1/16 " and " 10.0.0/24 . -And -.BI exact " PREFIX" -(or just -.IR PREFIX ")" -selects routes with this exact prefix. If neither of these options -are present, -.B ip -assumes -.BI root " 0/0" -i.e. it lists the entire table. - -.TP -.BI tos " TOS" -.BI dsfield " TOS" -only select routes with the given TOS. - -.TP -.BI table " TABLEID" -show the routes from this table(s). The default setting is to show -.BR table main "." -.I TABLEID -may either be the ID of a real table or one of the special values: -.sp -.in +8 -.B all -- list all of the tables. -.sp -.B cache -- dump the routing cache. -.in -8 - -.TP -.B cloned -.TP -.B cached -list cloned routes i.e. routes which were dynamically forked from -other routes because some route attribute (f.e. MTU) was updated. -Actually, it is equivalent to -.BR "table cache" "." - -.TP -.BI from " SELECTOR" -the same syntax as for -.BR to "," -but it binds the source address range rather than destinations. -Note that the -.B from -option only works with cloned routes. - -.TP -.BI protocol " RTPROTO" -only list routes of this protocol. - -.TP -.BI scope " SCOPE_VAL" -only list routes with this scope. - -.TP -.BI type " TYPE" -only list routes of this type. - -.TP -.BI dev " NAME" -only list routes going via this device. - -.TP -.BI via " PREFIX" -only list routes going via the nexthop routers selected by -.IR PREFIX "." - -.TP -.BI src " PREFIX" -only list routes with preferred source addresses selected -by -.IR PREFIX "." - -.TP -.BI realm " REALMID" -.TP -.BI realms " FROMREALM/TOREALM" -only list routes with these realms. - -.SS ip route flush - flush routing tables -this command flushes routes selected by some criteria. - -.sp -The arguments have the same syntax and semantics as the arguments of -.BR "ip route show" , -but routing tables are not listed but purged. The only difference is -the default action: -.B show -dumps all the IP main routing table but -.B flush -prints the helper page. - -.sp -With the -.B -statistics -option, the command becomes verbose. It prints out the number of -deleted routes and the number of rounds made to flush the routing -table. If the option is given -twice, -.B ip route flush -also dumps all the deleted routes in the format described in the -previous subsection. - -.SS ip route get - get a single route -this command gets a single route to a destination and prints its -contents exactly as the kernel sees it. - -.TP -.BI to " ADDRESS " (default) -the destination address. - -.TP -.BI from " ADDRESS" -the source address. - -.TP -.BI tos " TOS" -.TP -.BI dsfield " TOS" -the Type Of Service. - -.TP -.BI iif " NAME" -the device from which this packet is expected to arrive. - -.TP -.BI oif " NAME" -force the output device on which this packet will be routed. - -.TP -.B connected -if no source address -.RB "(option " from ")" -was given, relookup the route with the source set to the preferred -address received from the first lookup. -If policy routing is used, it may be a different route. - -.P -Note that this operation is not equivalent to -.BR "ip route show" . -.B show -shows existing routes. -.B get -resolves them and creates new clones if necessary. Essentially, -.B get -is equivalent to sending a packet along this path. -If the -.B iif -argument is not given, the kernel creates a route -to output packets towards the requested destination. -This is equivalent to pinging the destination -with a subsequent -.BR "ip route ls cache" , -however, no packets are actually sent. With the -.B iif -argument, the kernel pretends that a packet arrived from this interface -and searches for a path to forward the packet. - -.SH ip rule - routing policy database management - -.BR "Rule" s -in the routing policy database control the route selection algorithm. - -.P -Classic routing algorithms used in the Internet make routing decisions -based only on the destination address of packets (and in theory, -but not in practice, on the TOS field). - -.P -In some circumstances we want to route packets differently depending not only -on destination addresses, but also on other packet fields: source address, -IP protocol, transport protocol ports or even packet payload. -This task is called 'policy routing'. - -.P -To solve this task, the conventional destination based routing table, ordered -according to the longest match rule, is replaced with a 'routing policy -database' (or RPDB), which selects routes by executing some set of rules. - -.P -Each policy routing rule consists of a -.B selector -and an -.B action predicate. -The RPDB is scanned in the order of increasing priority. The selector -of each rule is applied to {source address, destination address, incoming -interface, tos, fwmark} and, if the selector matches the packet, -the action is performed. The action predicate may return with success. -In this case, it will either give a route or failure indication -and the RPDB lookup is terminated. Otherwise, the RPDB program -continues on the next rule. - -.P -Semantically, natural action is to select the nexthop and the output device. - -.P -At startup time the kernel configures the default RPDB consisting of three -rules: - -.TP -1. -Priority: 0, Selector: match anything, Action: lookup routing -table -.B local -(ID 255). -The -.B local -table is a special routing table containing -high priority control routes for local and broadcast addresses. -.sp -Rule 0 is special. It cannot be deleted or overridden. - -.TP -2. -Priority: 32766, Selector: match anything, Action: lookup routing -table -.B main -(ID 254). -The -.B main -table is the normal routing table containing all non-policy -routes. This rule may be deleted and/or overridden with other -ones by the administrator. - -.TP -3. -Priority: 32767, Selector: match anything, Action: lookup routing -table -.B default -(ID 253). -The -.B default -table is empty. It is reserved for some post-processing if no previous -default rules selected the packet. -This rule may also be deleted. - -.P -Each RPDB entry has additional -attributes. F.e. each rule has a pointer to some routing -table. NAT and masquerading rules have an attribute to select new IP -address to translate/masquerade. Besides that, rules have some -optional attributes, which routes have, namely -.BR "realms" . -These values do not override those contained in the routing tables. They -are only used if the route did not select any attributes. - -.sp -The RPDB may contain rules of the following types: - -.in +8 -.B unicast -- the rule prescribes to return the route found -in the routing table referenced by the rule. - -.B blackhole -- the rule prescribes to silently drop the packet. - -.B unreachable -- the rule prescribes to generate a 'Network is unreachable' error. - -.B prohibit -- the rule prescribes to generate 'Communication is administratively -prohibited' error. - -.B nat -- the rule prescribes to translate the source address -of the IP packet into some other value. -.in -8 - -.SS ip rule add - insert a new rule -.SS ip rule delete - delete a rule - -.TP -.BI type " TYPE " (default) -the type of this rule. The list of valid types was given in the previous -subsection. - -.TP -.BI from " PREFIX" -select the source prefix to match. - -.TP -.BI to " PREFIX" -select the destination prefix to match. - -.TP -.BI iif " NAME" -select the incoming device to match. If the interface is loopback, -the rule only matches packets originating from this host. This means -that you may create separate routing tables for forwarded and local -packets and, hence, completely segregate them. - -.TP -.BI tos " TOS" -.TP -.BI dsfield " TOS" -select the TOS value to match. - -.TP -.BI fwmark " MARK" -select the -.B fwmark -value to match. - -.TP -.BI priority " PREFERENCE" -the priority of this rule. Each rule should have an explicitly -set -.I unique -priority value. - -.TP -.BI table " TABLEID" -the routing table identifier to lookup if the rule selector matches. - -.TP -.BI realms " FROM/TO" -Realms to select if the rule matched and the routing table lookup -succeeded. Realm -.I TO -is only used if the route did not select any realm. - -.TP -.BI nat " ADDRESS" -The base of the IP address block to translate (for source addresses). -The -.I ADDRESS -may be either the start of the block of NAT addresses (selected by NAT -routes) or a local host address (or even zero). -In the last case the router does not translate the packets, but -masquerades them to this address. - -.B Warning: -Changes to the RPDB made with these commands do not become active -immediately. It is assumed that after a script finishes a batch of -updates, it flushes the routing cache with -.BR "ip route flush cache" . - -.SS ip rule flush - also dumps all the deleted rules. -This command has no arguments. - -.SS ip rule show - list rules -This command has no arguments. - -.SH ip maddress - multicast addresses management - -.B maddress -objects are multicast addresses. - -.SS ip maddress show - list multicast addresses - -.TP -.BI dev " NAME " (default) -the device name. - -.SS ip maddress add - add a multicast address -.SS ip maddress delete - delete a multicast address -these commands attach/detach a static link layer multicast address -to listen on the interface. -Note that it is impossible to join protocol multicast groups -statically. This command only manages link layer addresses. - -.TP -.BI address " LLADDRESS " (default) -the link layer multicast address. - -.TP -.BI dev " NAME" -the device to join/leave this multicast address. - -.SH ip mroute - multicast routing cache management -.B mroute -objects are multicast routing cache entries created by a user level -mrouting daemon (f.e. -.B pimd -or -.B mrouted -). - -Due to the limitations of the current interface to the multicast routing -engine, it is impossible to change -.B mroute -objects administratively, so we may only display them. This limitation -will be removed in the future. - -.SS ip mroute show - list mroute cache entries - -.TP -.BI to " PREFIX " (default) -the prefix selecting the destination multicast addresses to list. - -.TP -.BI iif " NAME" -the interface on which multicast packets are received. - -.TP -.BI from " PREFIX" -the prefix selecting the IP source addresses of the multicast route. - -.SH ip tunnel - tunnel configuration -.B tunnel -objects are tunnels, encapsulating packets in IPv4 packets and then -sending them over the IP infrastructure. - -.SS ip tunnel add - add a new tunnel -.SS ip tunnel change - change an existing tunnel -.SS ip tunnel delete - destroy a tunnel - -.TP -.BI name " NAME " (default) -select the tunnel device name. - -.TP -.BI mode " MODE" -set the tunnel mode. Three modes are currently available: -.BR ipip ", " sit " and " gre "." - -.TP -.BI remote " ADDRESS" -set the remote endpoint of the tunnel. - -.TP -.BI local " ADDRESS" -set the fixed local address for tunneled packets. -It must be an address on another interface of this host. - -.TP -.BI ttl " N" -set a fixed TTL -.I N -on tunneled packets. -.I N -is a number in the range 1--255. 0 is a special value -meaning that packets inherit the TTL value. -The default value is: -.BR "inherit" . - -.TP -.BI tos " T" -.TP -.BI dsfield " T" -set a fixed TOS -.I T -on tunneled packets. -The default value is: -.BR "inherit" . - -.TP -.BI dev " NAME" -bind the tunnel to the device -.I NAME -so that tunneled packets will only be routed via this device and will -not be able to escape to another device when the route to endpoint -changes. - -.TP -.B nopmtudisc -disable Path MTU Discovery on this tunnel. -It is enabled by default. Note that a fixed ttl is incompatible -with this option: tunnelling with a fixed ttl always makes pmtu -discovery. - -.TP -.BI key " K" -.TP -.BI ikey " K" -.TP -.BI okey " K" -.RB ( " only GRE tunnels " ) -use keyed GRE with key -.IR K ". " K -is either a number or an IP address-like dotted quad. -The -.B key -parameter sets the key to use in both directions. -The -.BR ikey " and " okey -parameters set different keys for input and output. - -.TP -.BR csum ", " icsum ", " ocsum -.RB ( " only GRE tunnels " ) -generate/require checksums for tunneled packets. -The -.B ocsum -flag calculates checksums for outgoing packets. -The -.B icsum -flag requires that all input packets have the correct -checksum. The -.B csum -flag is equivalent to the combination -.BR "icsum ocsum" . - -.TP -.BR seq ", " iseq ", " oseq -.RB ( " only GRE tunnels " ) -serialize packets. -The -.B oseq -flag enables sequencing of outgoing packets. -The -.B iseq -flag requires that all input packets are serialized. -The -.B seq -flag is equivalent to the combination -.BR "iseq oseq" . -.B It isn't work. Don't use it. - -.SS ip tunnel show - list tunnels -This command has no arguments. - -.SH ip monitor and rtmon - state monitoring - -The -.B ip -utility can monitor the state of devices, addresses -and routes continuously. This option has a slightly different format. -Namely, the -.B monitor -command is the first in the command line and then the object list follows: - -.BR "ip monitor" " [ " all " |" -.IR LISTofOBJECTS " ]" - -.I OBJECT-LIST -is the list of object types that we want to monitor. -It may contain -.BR link ", " address " and " route "." -If no -.B file -argument is given, -.B ip -opens RTNETLINK, listens on it and dumps state changes in the format -described in previous sections. - -.P -If a file name is given, it does not listen on RTNETLINK, -but opens the file containing RTNETLINK messages saved in binary format -and dumps them. Such a history file can be generated with the -.B rtmon -utility. This utility has a command line syntax similar to -.BR "ip monitor" . -Ideally, -.B rtmon -should be started before the first network configuration command -is issued. F.e. if you insert: -.sp -.in +8 -rtmon file /var/log/rtmon.log -.in -8 -.sp -in a startup script, you will be able to view the full history -later. - -.P -Certainly, it is possible to start -.B rtmon -at any time. -It prepends the history with the state snapshot dumped at the moment -of starting. - -.SH HISTORY -.B ip -was written by Alexey N. Kuznetsov and added in Linux 2.2. -.SH SEE ALSO -.BR tc (8) -.br -.RB "IP Command reference " ip-cref.ps -.br -.RB "IP tunnels " ip-cref.ps - -.SH AUTHOR -Original Manpage by Michail Litvak <mci@owl.openwall.com> diff --git a/man/man8/tc-cbq-details.8 b/man/man8/tc-cbq-details.8 deleted file mode 100644 index e47da62..0000000 --- a/man/man8/tc-cbq-details.8 +++ /dev/null @@ -1,425 +0,0 @@ -.TH CBQ 8 "8 December 2001" "iproute2" "Linux" -.SH NAME -CBQ \- Class Based Queueing -.SH SYNOPSIS -.B tc qdisc ... dev -dev -.B ( parent -classid -.B | root) [ handle -major: -.B ] cbq avpkt -bytes -.B bandwidth -rate -.B [ cell -bytes -.B ] [ ewma -log -.B ] [ mpu -bytes -.B ] - -.B tc class ... dev -dev -.B parent -major:[minor] -.B [ classid -major:minor -.B ] cbq allot -bytes -.B [ bandwidth -rate -.B ] [ rate -rate -.B ] prio -priority -.B [ weight -weight -.B ] [ minburst -packets -.B ] [ maxburst -packets -.B ] [ ewma -log -.B ] [ cell -bytes -.B ] avpkt -bytes -.B [ mpu -bytes -.B ] [ bounded isolated ] [ split -handle -.B & defmap -defmap -.B ] [ estimator -interval timeconstant -.B ] - -.SH DESCRIPTION -Class Based Queueing is a classful qdisc that implements a rich -linksharing hierarchy of classes. It contains shaping elements as -well as prioritizing capabilities. Shaping is performed using link -idle time calculations based on the timing of dequeue events and -underlying link bandwidth. - -.SH SHAPING ALGORITHM -Shaping is done using link idle time calculations, and actions taken if -these calculations deviate from set limits. - -When shaping a 10mbit/s connection to 1mbit/s, the link will -be idle 90% of the time. If it isn't, it needs to be throttled so that it -IS idle 90% of the time. - -From the kernel's perspective, this is hard to measure, so CBQ instead -derives the idle time from the number of microseconds (in fact, jiffies) -that elapse between requests from the device driver for more data. Combined -with the knowledge of packet sizes, this is used to approximate how full or -empty the link is. - -This is rather circumspect and doesn't always arrive at proper -results. For example, what is the actual link speed of an interface -that is not really able to transmit the full 100mbit/s of data, -perhaps because of a badly implemented driver? A PCMCIA network card -will also never achieve 100mbit/s because of the way the bus is -designed - again, how do we calculate the idle time? - -The physical link bandwidth may be ill defined in case of not-quite-real -network devices like PPP over Ethernet or PPTP over TCP/IP. The effective -bandwidth in that case is probably determined by the efficiency of pipes -to userspace - which not defined. - -During operations, the effective idletime is measured using an -exponential weighted moving average (EWMA), which considers recent -packets to be exponentially more important than past ones. The Unix -loadaverage is calculated in the same way. - -The calculated idle time is subtracted from the EWMA measured one, -the resulting number is called 'avgidle'. A perfectly loaded link has -an avgidle of zero: packets arrive exactly at the calculated -interval. - -An overloaded link has a negative avgidle and if it gets too negative, -CBQ throttles and is then 'overlimit'. - -Conversely, an idle link might amass a huge avgidle, which would then -allow infinite bandwidths after a few hours of silence. To prevent -this, avgidle is capped at -.B maxidle. - -If overlimit, in theory, the CBQ could throttle itself for exactly the -amount of time that was calculated to pass between packets, and then -pass one packet, and throttle again. Due to timer resolution constraints, -this may not be feasible, see the -.B minburst -parameter below. - -.SH CLASSIFICATION -Within the one CBQ instance many classes may exist. Each of these classes -contains another qdisc, by default -.BR tc-pfifo (8). - -When enqueueing a packet, CBQ starts at the root and uses various methods to -determine which class should receive the data. If a verdict is reached, this -process is repeated for the recipient class which might have further -means of classifying traffic to its children, if any. - -CBQ has the following methods available to classify a packet to any child -classes. -.TP -(i) -.B skb->priority class encoding. -Can be set from userspace by an application with the -.B SO_PRIORITY -setsockopt. -The -.B skb->priority class encoding -only applies if the skb->priority holds a major:minor handle of an existing -class within this qdisc. -.TP -(ii) -tc filters attached to the class. -.TP -(iii) -The defmap of a class, as set with the -.B split & defmap -parameters. The defmap may contain instructions for each possible Linux packet -priority. - -.P -Each class also has a -.B level. -Leaf nodes, attached to the bottom of the class hierarchy, have a level of 0. -.SH CLASSIFICATION ALGORITHM - -Classification is a loop, which terminates when a leaf class is found. At any -point the loop may jump to the fallback algorithm. - -The loop consists of the following steps: -.TP -(i) -If the packet is generated locally and has a valid classid encoded within its -.B skb->priority, -choose it and terminate. - -.TP -(ii) -Consult the tc filters, if any, attached to this child. If these return -a class which is not a leaf class, restart loop from the class returned. -If it is a leaf, choose it and terminate. -.TP -(iii) -If the tc filters did not return a class, but did return a classid, -try to find a class with that id within this qdisc. -Check if the found class is of a lower -.B level -than the current class. If so, and the returned class is not a leaf node, -restart the loop at the found class. If it is a leaf node, terminate. -If we found an upward reference to a higher level, enter the fallback -algorithm. -.TP -(iv) -If the tc filters did not return a class, nor a valid reference to one, -consider the minor number of the reference to be the priority. Retrieve -a class from the defmap of this class for the priority. If this did not -contain a class, consult the defmap of this class for the -.B BEST_EFFORT -class. If this is an upward reference, or no -.B BEST_EFFORT -class was defined, -enter the fallback algorithm. If a valid class was found, and it is not a -leaf node, restart the loop at this class. If it is a leaf, choose it and -terminate. If -neither the priority distilled from the classid, nor the -.B BEST_EFFORT -priority yielded a class, enter the fallback algorithm. -.P -The fallback algorithm resides outside of the loop and is as follows. -.TP -(i) -Consult the defmap of the class at which the jump to fallback occured. If -the defmap contains a class for the -.B -priority -of the class (which is related to the TOS field), choose this class and -terminate. -.TP -(ii) -Consult the map for a class for the -.B BEST_EFFORT -priority. If found, choose it, and terminate. -.TP -(iii) -Choose the class at which break out to the fallback algorithm occured. Terminate. -.P -The packet is enqueued to the class which was chosen when either algorithm -terminated. It is therefore possible for a packet to be enqueued *not* at a -leaf node, but in the middle of the hierarchy. - -.SH LINK SHARING ALGORITHM -When dequeuing for sending to the network device, CBQ decides which of its -classes will be allowed to send. It does so with a Weighted Round Robin process -in which each class with packets gets a chance to send in turn. The WRR process -starts by asking the highest priority classes (lowest numerically - -highest semantically) for packets, and will continue to do so until they -have no more data to offer, in which case the process repeats for lower -priorities. - -.B CERTAINTY ENDS HERE, ANK PLEASE HELP - -Each class is not allowed to send at length though - they can only dequeue a -configurable amount of data during each round. - -If a class is about to go overlimit, and it is not -.B bounded -it will try to borrow avgidle from siblings that are not -.B isolated. -This process is repeated from the bottom upwards. If a class is unable -to borrow enough avgidle to send a packet, it is throttled and not asked -for a packet for enough time for the avgidle to increase above zero. - -.B I REALLY NEED HELP FIGURING THIS OUT. REST OF DOCUMENT IS PRETTY CERTAIN -.B AGAIN. - -.SH QDISC -The root qdisc of a CBQ class tree has the following parameters: - -.TP -parent major:minor | root -This mandatory parameter determines the place of the CBQ instance, either at the -.B root -of an interface or within an existing class. -.TP -handle major: -Like all other qdiscs, the CBQ can be assigned a handle. Should consist only -of a major number, followed by a colon. Optional. -.TP -avpkt bytes -For calculations, the average packet size must be known. It is silently capped -at a minimum of 2/3 of the interface MTU. Mandatory. -.TP -bandwidth rate -To determine the idle time, CBQ must know the bandwidth of your underlying -physical interface, or parent qdisc. This is a vital parameter, more about it -later. Mandatory. -.TP -cell -The cell size determines he granularity of packet transmission time calculations. Has a sensible default. -.TP -mpu -A zero sized packet may still take time to transmit. This value is the lower -cap for packet transmission time calculations - packets smaller than this value -are still deemed to have this size. Defaults to zero. -.TP -ewma log -When CBQ needs to measure the average idle time, it does so using an -Exponentially Weighted Moving Average which smoothes out measurements into -a moving average. The EWMA LOG determines how much smoothing occurs. Defaults -to 5. Lower values imply greater sensitivity. Must be between 0 and 31. -.P -A CBQ qdisc does not shape out of its own accord. It only needs to know certain -parameters about the underlying link. Actual shaping is done in classes. - -.SH CLASSES -Classes have a host of parameters to configure their operation. - -.TP -parent major:minor -Place of this class within the hierarchy. If attached directly to a qdisc -and not to another class, minor can be omitted. Mandatory. -.TP -classid major:minor -Like qdiscs, classes can be named. The major number must be equal to the -major number of the qdisc to which it belongs. Optional, but needed if this -class is going to have children. -.TP -weight weight -When dequeuing to the interface, classes are tried for traffic in a -round-robin fashion. Classes with a higher configured qdisc will generally -have more traffic to offer during each round, so it makes sense to allow -it to dequeue more traffic. All weights under a class are normalized, so -only the ratios matter. Defaults to the configured rate, unless the priority -of this class is maximal, in which case it is set to 1. -.TP -allot bytes -Allot specifies how many bytes a qdisc can dequeue -during each round of the process. This parameter is weighted using the -renormalized class weight described above. - -.TP -priority priority -In the round-robin process, classes with the lowest priority field are tried -for packets first. Mandatory. - -.TP -rate rate -Maximum rate this class and all its children combined can send at. Mandatory. - -.TP -bandwidth rate -This is different from the bandwidth specified when creating a CBQ disc. Only -used to determine maxidle and offtime, which are only calculated when -specifying maxburst or minburst. Mandatory if specifying maxburst or minburst. - -.TP -maxburst -This number of packets is used to calculate maxidle so that when -avgidle is at maxidle, this number of average packets can be burst -before avgidle drops to 0. Set it higher to be more tolerant of -bursts. You can't set maxidle directly, only via this parameter. - -.TP -minburst -As mentioned before, CBQ needs to throttle in case of -overlimit. The ideal solution is to do so for exactly the calculated -idle time, and pass 1 packet. However, Unix kernels generally have a -hard time scheduling events shorter than 10ms, so it is better to -throttle for a longer period, and then pass minburst packets in one -go, and then sleep minburst times longer. - -The time to wait is called the offtime. Higher values of minburst lead -to more accurate shaping in the long term, but to bigger bursts at -millisecond timescales. - -.TP -minidle -If avgidle is below 0, we are overlimits and need to wait until -avgidle will be big enough to send one packet. To prevent a sudden -burst from shutting down the link for a prolonged period of time, -avgidle is reset to minidle if it gets too low. - -Minidle is specified in negative microseconds, so 10 means that -avgidle is capped at -10us. - -.TP -bounded -Signifies that this class will not borrow bandwidth from its siblings. -.TP -isolated -Means that this class will not borrow bandwidth to its siblings - -.TP -split major:minor & defmap bitmap[/bitmap] -If consulting filters attached to a class did not give a verdict, -CBQ can also classify based on the packet's priority. There are 16 -priorities available, numbered from 0 to 15. - -The defmap specifies which priorities this class wants to receive, -specified as a bitmap. The Least Significant Bit corresponds to priority -zero. The -.B split -parameter tells CBQ at which class the decision must be made, which should -be a (grand)parent of the class you are adding. - -As an example, 'tc class add ... classid 10:1 cbq .. split 10:0 defmap c0' -configures class 10:0 to send packets with priorities 6 and 7 to 10:1. - -The complimentary configuration would then -be: 'tc class add ... classid 10:2 cbq ... split 10:0 defmap 3f' -Which would send all packets 0, 1, 2, 3, 4 and 5 to 10:1. -.TP -estimator interval timeconstant -CBQ can measure how much bandwidth each class is using, which tc filters -can use to classify packets with. In order to determine the bandwidth -it uses a very simple estimator that measures once every -.B interval -microseconds how much traffic has passed. This again is a EWMA, for which -the time constant can be specified, also in microseconds. The -.B time constant -corresponds to the sluggishness of the measurement or, conversely, to the -sensitivity of the average to short bursts. Higher values mean less -sensitivity. - - - -.SH SOURCES -.TP -o -Sally Floyd and Van Jacobson, "Link-sharing and Resource -Management Models for Packet Networks", -IEEE/ACM Transactions on Networking, Vol.3, No.4, 1995 - -.TP -o -Sally Floyd, "Notes on CBQ and Guarantee Service", 1995 - -.TP -o -Sally Floyd, "Notes on Class-Based Queueing: Setting -Parameters", 1996 - -.TP -o -Sally Floyd and Michael Speer, "Experimental Results -for Class-Based Queueing", 1998, not published. - - - -.SH SEE ALSO -.BR tc (8) - -.SH AUTHOR -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>. This manpage maintained by -bert hubert <ahu@ds9a.nl> - - diff --git a/man/man8/tc-cbq.8 b/man/man8/tc-cbq.8 deleted file mode 100644 index 79fb93b..0000000 --- a/man/man8/tc-cbq.8 +++ /dev/null @@ -1,353 +0,0 @@ -.TH CBQ 8 "16 December 2001" "iproute2" "Linux" -.SH NAME -CBQ \- Class Based Queueing -.SH SYNOPSIS -.B tc qdisc ... dev -dev -.B ( parent -classid -.B | root) [ handle -major: -.B ] cbq [ allot -bytes -.B ] avpkt -bytes -.B bandwidth -rate -.B [ cell -bytes -.B ] [ ewma -log -.B ] [ mpu -bytes -.B ] - -.B tc class ... dev -dev -.B parent -major:[minor] -.B [ classid -major:minor -.B ] cbq allot -bytes -.B [ bandwidth -rate -.B ] [ rate -rate -.B ] prio -priority -.B [ weight -weight -.B ] [ minburst -packets -.B ] [ maxburst -packets -.B ] [ ewma -log -.B ] [ cell -bytes -.B ] avpkt -bytes -.B [ mpu -bytes -.B ] [ bounded isolated ] [ split -handle -.B & defmap -defmap -.B ] [ estimator -interval timeconstant -.B ] - -.SH DESCRIPTION -Class Based Queueing is a classful qdisc that implements a rich -linksharing hierarchy of classes. It contains shaping elements as -well as prioritizing capabilities. Shaping is performed using link -idle time calculations based on the timing of dequeue events and -underlying link bandwidth. - -.SH SHAPING ALGORITHM -When shaping a 10mbit/s connection to 1mbit/s, the link will -be idle 90% of the time. If it isn't, it needs to be throttled so that it -IS idle 90% of the time. - -During operations, the effective idletime is measured using an -exponential weighted moving average (EWMA), which considers recent -packets to be exponentially more important than past ones. The Unix -loadaverage is calculated in the same way. - -The calculated idle time is subtracted from the EWMA measured one, -the resulting number is called 'avgidle'. A perfectly loaded link has -an avgidle of zero: packets arrive exactly at the calculated -interval. - -An overloaded link has a negative avgidle and if it gets too negative, -CBQ throttles and is then 'overlimit'. - -Conversely, an idle link might amass a huge avgidle, which would then -allow infinite bandwidths after a few hours of silence. To prevent -this, avgidle is capped at -.B maxidle. - -If overlimit, in theory, the CBQ could throttle itself for exactly the -amount of time that was calculated to pass between packets, and then -pass one packet, and throttle again. Due to timer resolution constraints, -this may not be feasible, see the -.B minburst -parameter below. - -.SH CLASSIFICATION -Within the one CBQ instance many classes may exist. Each of these classes -contains another qdisc, by default -.BR tc-pfifo (8). - -When enqueueing a packet, CBQ starts at the root and uses various methods to -determine which class should receive the data. - -In the absence of uncommon configuration options, the process is rather easy. -At each node we look for an instruction, and then go to the class the -instruction refers us to. If the class found is a barren leaf-node (without -children), we enqueue the packet there. If it is not yet a leaf node, we do -the whole thing over again starting from that node. - -The following actions are performed, in order at each node we visit, until one -sends us to another node, or terminates the process. -.TP -(i) -Consult filters attached to the class. If sent to a leafnode, we are done. -Otherwise, restart. -.TP -(ii) -Consult the defmap for the priority assigned to this packet, which depends -on the TOS bits. Check if the referral is leafless, otherwise restart. -.TP -(iii) -Ask the defmap for instructions for the 'best effort' priority. Check the -answer for leafness, otherwise restart. -.TP -(iv) -If none of the above returned with an instruction, enqueue at this node. -.P -This algorithm makes sure that a packet always ends up somewhere, even while -you are busy building your configuration. - -For more details, see -.BR tc-cbq-details(8). - -.SH LINK SHARING ALGORITHM -When dequeuing for sending to the network device, CBQ decides which of its -classes will be allowed to send. It does so with a Weighted Round Robin process -in which each class with packets gets a chance to send in turn. The WRR process -starts by asking the highest priority classes (lowest numerically - -highest semantically) for packets, and will continue to do so until they -have no more data to offer, in which case the process repeats for lower -priorities. - -Classes by default borrow bandwidth from their siblings. A class can be -prevented from doing so by declaring it 'bounded'. A class can also indicate -its unwillingness to lend out bandwidth by being 'isolated'. - -.SH QDISC -The root of a CBQ qdisc class tree has the following parameters: - -.TP -parent major:minor | root -This mandatory parameter determines the place of the CBQ instance, either at the -.B root -of an interface or within an existing class. -.TP -handle major: -Like all other qdiscs, the CBQ can be assigned a handle. Should consist only -of a major number, followed by a colon. Optional, but very useful if classes -will be generated within this qdisc. -.TP -allot bytes -This allotment is the 'chunkiness' of link sharing and is used for determining packet -transmission time tables. The qdisc allot differs slightly from the class allot discussed -below. Optional. Defaults to a reasonable value, related to avpkt. -.TP -avpkt bytes -The average size of a packet is needed for calculating maxidle, and is also used -for making sure 'allot' has a safe value. Mandatory. -.TP -bandwidth rate -To determine the idle time, CBQ must know the bandwidth of your underlying -physical interface, or parent qdisc. This is a vital parameter, more about it -later. Mandatory. -.TP -cell -The cell size determines he granularity of packet transmission time calculations. Has a sensible default. -.TP -mpu -A zero sized packet may still take time to transmit. This value is the lower -cap for packet transmission time calculations - packets smaller than this value -are still deemed to have this size. Defaults to zero. -.TP -ewma log -When CBQ needs to measure the average idle time, it does so using an -Exponentially Weighted Moving Average which smoothes out measurements into -a moving average. The EWMA LOG determines how much smoothing occurs. Lower -values imply greater sensitivity. Must be between 0 and 31. Defaults -to 5. -.P -A CBQ qdisc does not shape out of its own accord. It only needs to know certain -parameters about the underlying link. Actual shaping is done in classes. - -.SH CLASSES -Classes have a host of parameters to configure their operation. - -.TP -parent major:minor -Place of this class within the hierarchy. If attached directly to a qdisc -and not to another class, minor can be omitted. Mandatory. -.TP -classid major:minor -Like qdiscs, classes can be named. The major number must be equal to the -major number of the qdisc to which it belongs. Optional, but needed if this -class is going to have children. -.TP -weight weight -When dequeuing to the interface, classes are tried for traffic in a -round-robin fashion. Classes with a higher configured qdisc will generally -have more traffic to offer during each round, so it makes sense to allow -it to dequeue more traffic. All weights under a class are normalized, so -only the ratios matter. Defaults to the configured rate, unless the priority -of this class is maximal, in which case it is set to 1. -.TP -allot bytes -Allot specifies how many bytes a qdisc can dequeue -during each round of the process. This parameter is weighted using the -renormalized class weight described above. Silently capped at a minimum of -3/2 avpkt. Mandatory. - -.TP -prio priority -In the round-robin process, classes with the lowest priority field are tried -for packets first. Mandatory. - -.TP -avpkt -See the QDISC section. - -.TP -rate rate -Maximum rate this class and all its children combined can send at. Mandatory. - -.TP -bandwidth rate -This is different from the bandwidth specified when creating a CBQ disc! Only -used to determine maxidle and offtime, which are only calculated when -specifying maxburst or minburst. Mandatory if specifying maxburst or minburst. - -.TP -maxburst -This number of packets is used to calculate maxidle so that when -avgidle is at maxidle, this number of average packets can be burst -before avgidle drops to 0. Set it higher to be more tolerant of -bursts. You can't set maxidle directly, only via this parameter. - -.TP -minburst -As mentioned before, CBQ needs to throttle in case of -overlimit. The ideal solution is to do so for exactly the calculated -idle time, and pass 1 packet. However, Unix kernels generally have a -hard time scheduling events shorter than 10ms, so it is better to -throttle for a longer period, and then pass minburst packets in one -go, and then sleep minburst times longer. - -The time to wait is called the offtime. Higher values of minburst lead -to more accurate shaping in the long term, but to bigger bursts at -millisecond timescales. Optional. - -.TP -minidle -If avgidle is below 0, we are overlimits and need to wait until -avgidle will be big enough to send one packet. To prevent a sudden -burst from shutting down the link for a prolonged period of time, -avgidle is reset to minidle if it gets too low. - -Minidle is specified in negative microseconds, so 10 means that -avgidle is capped at -10us. Optional. - -.TP -bounded -Signifies that this class will not borrow bandwidth from its siblings. -.TP -isolated -Means that this class will not borrow bandwidth to its siblings - -.TP -split major:minor & defmap bitmap[/bitmap] -If consulting filters attached to a class did not give a verdict, -CBQ can also classify based on the packet's priority. There are 16 -priorities available, numbered from 0 to 15. - -The defmap specifies which priorities this class wants to receive, -specified as a bitmap. The Least Significant Bit corresponds to priority -zero. The -.B split -parameter tells CBQ at which class the decision must be made, which should -be a (grand)parent of the class you are adding. - -As an example, 'tc class add ... classid 10:1 cbq .. split 10:0 defmap c0' -configures class 10:0 to send packets with priorities 6 and 7 to 10:1. - -The complimentary configuration would then -be: 'tc class add ... classid 10:2 cbq ... split 10:0 defmap 3f' -Which would send all packets 0, 1, 2, 3, 4 and 5 to 10:1. -.TP -estimator interval timeconstant -CBQ can measure how much bandwidth each class is using, which tc filters -can use to classify packets with. In order to determine the bandwidth -it uses a very simple estimator that measures once every -.B interval -microseconds how much traffic has passed. This again is a EWMA, for which -the time constant can be specified, also in microseconds. The -.B time constant -corresponds to the sluggishness of the measurement or, conversely, to the -sensitivity of the average to short bursts. Higher values mean less -sensitivity. - -.SH BUGS -The actual bandwidth of the underlying link may not be known, for example -in the case of PPoE or PPTP connections which in fact may send over a -pipe, instead of over a physical device. CBQ is quite resilient to major -errors in the configured bandwidth, probably a the cost of coarser shaping. - -Default kernels rely on coarse timing information for making decisions. These -may make shaping precise in the long term, but inaccurate on second long scales. - -See -.BR tc-cbq-details(8) -for hints on how to improve this. - -.SH SOURCES -.TP -o -Sally Floyd and Van Jacobson, "Link-sharing and Resource -Management Models for Packet Networks", -IEEE/ACM Transactions on Networking, Vol.3, No.4, 1995 - -.TP -o -Sally Floyd, "Notes on CBQ and Guaranteed Service", 1995 - -.TP -o -Sally Floyd, "Notes on Class-Based Queueing: Setting -Parameters", 1996 - -.TP -o -Sally Floyd and Michael Speer, "Experimental Results -for Class-Based Queueing", 1998, not published. - - - -.SH SEE ALSO -.BR tc (8) - -.SH AUTHOR -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>. This manpage maintained by -bert hubert <ahu@ds9a.nl> - - diff --git a/man/man8/tc-htb.8 b/man/man8/tc-htb.8 deleted file mode 100644 index f61b818..0000000 --- a/man/man8/tc-htb.8 +++ /dev/null @@ -1,150 +0,0 @@ -.TH HTB 8 "10 January 2002" "iproute2" "Linux" -.SH NAME -HTB \- Hierarchy Token Bucket -.SH SYNOPSIS -.B tc qdisc ... dev -dev -.B ( parent -classid -.B | root) [ handle -major: -.B ] htb [ default -minor-id -.B ] - -.B tc class ... dev -dev -.B parent -major:[minor] -.B [ classid -major:minor -.B ] htb rate -rate -.B [ ceil -rate -.B ] burst -bytes -.B [ cburst -bytes -.B ] [ prio -priority -.B ] - -.SH DESCRIPTION -HTB is meant as a more understandable and intuitive replacement for -the CBQ qdisc in Linux. Both CBQ and HTB help you to control the use -of the outbound bandwidth on a given link. Both allow you to use one -physical link to simulate several slower links and to send different -kinds of traffic on different simulated links. In both cases, you have -to specify how to divide the physical link into simulated links and -how to decide which simulated link to use for a given packet to be sent. - -Unlike CBQ, HTB shapes traffic based on the Token Bucket Filter algorithm -which does not depend on interface characteristics and so does not need to -know the underlying bandwidth of the outgoing interface. - -.SH SHAPING ALGORITHM -Shaping works as documented in -.B tc-tbf (8). - -.SH CLASSIFICATION -Within the one HRB instance many classes may exist. Each of these classes -contains another qdisc, by default -.BR tc-pfifo (8). - -When enqueueing a packet, HTB starts at the root and uses various methods to -determine which class should receive the data. - -In the absence of uncommon configuration options, the process is rather easy. -At each node we look for an instruction, and then go to the class the -instruction refers us to. If the class found is a barren leaf-node (without -children), we enqueue the packet there. If it is not yet a leaf node, we do -the whole thing over again starting from that node. - -The following actions are performed, in order at each node we visit, until one -sends us to another node, or terminates the process. -.TP -(i) -Consult filters attached to the class. If sent to a leafnode, we are done. -Otherwise, restart. -.TP -(ii) -If none of the above returned with an instruction, enqueue at this node. -.P -This algorithm makes sure that a packet always ends up somewhere, even while -you are busy building your configuration. - -.SH LINK SHARING ALGORITHM -FIXME - -.SH QDISC -The root of a HTB qdisc class tree has the following parameters: - -.TP -parent major:minor | root -This mandatory parameter determines the place of the HTB instance, either at the -.B root -of an interface or within an existing class. -.TP -handle major: -Like all other qdiscs, the HTB can be assigned a handle. Should consist only -of a major number, followed by a colon. Optional, but very useful if classes -will be generated within this qdisc. -.TP -default minor-id -Unclassified traffic gets sent to the class with this minor-id. - -.SH CLASSES -Classes have a host of parameters to configure their operation. - -.TP -parent major:minor -Place of this class within the hierarchy. If attached directly to a qdisc -and not to another class, minor can be omitted. Mandatory. -.TP -classid major:minor -Like qdiscs, classes can be named. The major number must be equal to the -major number of the qdisc to which it belongs. Optional, but needed if this -class is going to have children. -.TP -prio priority -In the round-robin process, classes with the lowest priority field are tried -for packets first. Mandatory. - -.TP -rate rate -Maximum rate this class and all its children are guaranteed. Mandatory. - -.TP -ceil rate -Maximum rate at which a class can send, if its parent has bandwidth to spare. -Defaults to the configured rate, which implies no borrowing - -.TP -burst bytes -Amount of bytes that can be burst at -.B ceil -speed, in excess of the configured -.B rate. -Should be at least as high as the highest burst of all children. - -.TP -cburst bytes -Amount of bytes that can be burst at 'infinite' speed, in other words, as fast -as the interface can transmit them. For perfect evening out, should be equal to at most one average -packet. Should be at least as high as the highest cburst of all children. - -.SH NOTES -Due to Unix timing constraints, the maximum ceil rate is not infinite and may in fact be quite low. On Intel, -there are 100 timer events per second, the maximum rate is that rate at which 'burst' bytes are sent each timer tick. -From this, the mininum burst size for a specified rate can be calculated. For i386, a 10mbit rate requires a 12 kilobyte -burst as 100*12kb*8 equals 10mbit. - -.SH SEE ALSO -.BR tc (8) -.P -HTB website: http://luxik.cdi.cz/~devik/qos/htb/ -.SH AUTHOR -Martin Devera <devik@cdi.cz>. This manpage maintained by bert hubert <ahu@ds9a.nl> - - diff --git a/man/man8/tc-pbfifo.8 b/man/man8/tc-pbfifo.8 deleted file mode 100644 index 8dda4bb..0000000 --- a/man/man8/tc-pbfifo.8 +++ /dev/null @@ -1,72 +0,0 @@ -.TH PBFIFO 8 "10 January 2002" "iproute2" "Linux" -.SH NAME -pfifo \- Packet limited First In, First Out queue -.P -bfifo \- Byte limited First In, First Out queue - -.SH SYNOPSIS -.B tc qdisc ... add pfifo -.B [ limit -packets -.B ] -.P -.B tc qdisc ... add bfifo -.B [ limit -bytes -.B ] - -.SH DESCRIPTION -The pfifo and bfifo qdiscs are unadorned First In, First Out queues. They are the -simplest queues possible and therefore have no overhead. -.B pfifo -constrains the queue size as measured in packets. -.B bfifo -does so as measured in bytes. - -Like all non-default qdiscs, they maintain statistics. This might be a reason to prefer -pfifo or bfifo over the default. - -.SH ALGORITHM -A list of packets is maintained, when a packet is enqueued it gets inserted at the tail of -a list. When a packet needs to be sent out to the network, it is taken from the head of the list. - -If the list is too long, no further packets are allowed on. This is called 'tail drop'. - -.SH PARAMETERS -.TP -limit -Maximum queue size. Specified in bytes for bfifo, in packets for pfifo. For pfifo, defaults -to the interface txqueuelen, as specified with -.BR ifconfig (8) -or -.BR ip (8). - -For bfifo, it defaults to the txqueuelen multiplied by the interface MTU. - -.SH OUTPUT -The output of -.B tc -s qdisc ls -contains the limit, either in packets or in bytes, and the number of bytes -and packets actually sent. An unsent and dropped packet only appears between braces -and is not counted as 'Sent'. - -In this example, the queue length is 100 packets, 45894 bytes were sent over 681 packets. -No packets were dropped, and as the pfifo queue does not slow down packets, there were also no -overlimits: -.P -.nf -# tc -s qdisc ls dev eth0 -qdisc pfifo 8001: dev eth0 limit 100p - Sent 45894 bytes 681 pkts (dropped 0, overlimits 0) -.fi - -If a backlog occurs, this is displayed as well. -.SH SEE ALSO -.BR tc (8) - -.SH AUTHORS -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru> - -This manpage maintained by bert hubert <ahu@ds9a.nl> - - diff --git a/man/man8/tc-pfifo.8 b/man/man8/tc-pfifo.8 deleted file mode 100644 index e69de29..0000000 diff --git a/man/man8/tc-pfifo_fast.8 b/man/man8/tc-pfifo_fast.8 deleted file mode 100644 index 43ab166..0000000 --- a/man/man8/tc-pfifo_fast.8 +++ /dev/null @@ -1,59 +0,0 @@ -.TH PFIFO_FAST 8 "10 January 2002" "iproute2" "Linux" -.SH NAME -pfifo_fast \- three-band first in, first out queue - -.SH DESCRIPTION -pfifo_fast is the default qdisc of each interface. - -Whenever an interface is created, the pfifo_fast qdisc is automatically used -as a queue. If another qdisc is attached, it preempts the default -pfifo_fast, which automatically returns to function when an existing qdisc -is detached. - -In this sense this qdisc is magic, and unlike other qdiscs. - -.SH ALGORITHM -The algorithm is very similar to that of the classful -.BR tc-prio (8) -qdisc. -.B pfifo_fast -is like three -.BR tc-pfifo (8) -queues side by side, where packets can be enqueued in any of the three bands -based on their Type of Service bits or assigned priority. - -Not all three bands are dequeued simultaneously - as long as lower bands -have traffic, higher bands are never dequeued. This can be used to -prioritize interactive traffic or penalize 'lowest cost' traffic. - -Each band can be txqueuelen packets long, as configured with -.BR ifconfig (8) -or -.BR ip (8). -Additional packets coming in are not enqueued but are instead dropped. - -See -.BR tc-prio (8) -for complete details on how TOS bits are translated into bands. -.SH PARAMETERS -.TP -txqueuelen -The length of the three bands depends on the interface txqueuelen, as -specified with -.BR ifconfig (8) -or -.BR ip (8). - -.SH BUGS -Does not maintain statistics and does not show up in tc qdisc ls. This is because -it is the automatic default in the absence of a configured qdisc. - -.SH SEE ALSO -.BR tc (8) - -.SH AUTHORS -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru> - -This manpage maintained by bert hubert <ahu@ds9a.nl> - - diff --git a/man/man8/tc-prio.8 b/man/man8/tc-prio.8 deleted file mode 100644 index e942e62..0000000 --- a/man/man8/tc-prio.8 +++ /dev/null @@ -1,187 +0,0 @@ -.TH PRIO 8 "16 December 2001" "iproute2" "Linux" -.SH NAME -PRIO \- Priority qdisc -.SH SYNOPSIS -.B tc qdisc ... dev -dev -.B ( parent -classid -.B | root) [ handle -major: -.B ] prio [ bands -bands -.B ] [ priomap -band,band,band... -.B ] [ estimator -interval timeconstant -.B ] - -.SH DESCRIPTION -The PRIO qdisc is a simple classful queueing discipline that contains -an arbitrary number of classes of differing priority. The classes are -dequeued in numerical descending order of priority. PRIO is a scheduler -and never delays packets - it is a work-conserving qdisc, though the qdiscs -contained in the classes may not be. - -Very useful for lowering latency when there is no need for slowing down -traffic. - -.SH ALGORITHM -On creation with 'tc qdisc add', a fixed number of bands is created. Each -band is a class, although is not possible to add classes with 'tc qdisc -add', the number of bands to be created must instead be specified on the -commandline attaching PRIO to its root. - -When dequeueing, band 0 is tried first and only if it did not deliver a -packet does PRIO try band 1, and so onwards. Maximum reliability packets -should therefore go to band 0, minimum delay to band 1 and the rest to band -2. - -As the PRIO qdisc itself will have minor number 0, band 0 is actually -major:1, band 1 is major:2, etc. For major, substitute the major number -assigned to the qdisc on 'tc qdisc add' with the -.B handle -parameter. - -.SH CLASSIFICATION -Three methods are available to PRIO to determine in which band a packet will -be enqueued. -.TP -From userspace -A process with sufficient privileges can encode the destination class -directly with SO_PRIORITY, see -.BR tc(7). -.TP -with a tc filter -A tc filter attached to the root qdisc can point traffic directly to a class -.TP -with the priomap -Based on the packet priority, which in turn is derived from the Type of -Service assigned to the packet. -.P -Only the priomap is specific to this qdisc. -.SH QDISC PARAMETERS -.TP -bands -Number of bands. If changed from the default of 3, -.B priomap -must be updated as well. -.TP -priomap -The priomap maps the priority of -a packet to a class. The priority can either be set directly from userspace, -or be derived from the Type of Service of the packet. - -Determines how packet priorities, as assigned by the kernel, map to -bands. Mapping occurs based on the TOS octet of the packet, which looks like -this: - -.nf -0 1 2 3 4 5 6 7 -+---+---+---+---+---+---+---+---+ -| | | | -|PRECEDENCE | TOS |MBZ| -| | | | -+---+---+---+---+---+---+---+---+ -.fi - -The four TOS bits (the 'TOS field') are defined as: - -.nf -Binary Decimcal Meaning ------------------------------------------ -1000 8 Minimize delay (md) -0100 4 Maximize throughput (mt) -0010 2 Maximize reliability (mr) -0001 1 Minimize monetary cost (mmc) -0000 0 Normal Service -.fi - -As there is 1 bit to the right of these four bits, the actual value of the -TOS field is double the value of the TOS bits. Tcpdump -v -v shows you the -value of the entire TOS field, not just the four bits. It is the value you -see in the first column of this table: - -.nf -TOS Bits Means Linux Priority Band ------------------------------------------------------------- -0x0 0 Normal Service 0 Best Effort 1 -0x2 1 Minimize Monetary Cost 1 Filler 2 -0x4 2 Maximize Reliability 0 Best Effort 1 -0x6 3 mmc+mr 0 Best Effort 1 -0x8 4 Maximize Throughput 2 Bulk 2 -0xa 5 mmc+mt 2 Bulk 2 -0xc 6 mr+mt 2 Bulk 2 -0xe 7 mmc+mr+mt 2 Bulk 2 -0x10 8 Minimize Delay 6 Interactive 0 -0x12 9 mmc+md 6 Interactive 0 -0x14 10 mr+md 6 Interactive 0 -0x16 11 mmc+mr+md 6 Interactive 0 -0x18 12 mt+md 4 Int. Bulk 1 -0x1a 13 mmc+mt+md 4 Int. Bulk 1 -0x1c 14 mr+mt+md 4 Int. Bulk 1 -0x1e 15 mmc+mr+mt+md 4 Int. Bulk 1 -.fi - -The second column contains the value of the relevant -four TOS bits, followed by their translated meaning. For example, 15 stands -for a packet wanting Minimal Montetary Cost, Maximum Reliability, Maximum -Throughput AND Minimum Delay. - -The fourth column lists the way the Linux kernel interprets the TOS bits, by -showing to which Priority they are mapped. - -The last column shows the result of the default priomap. On the commandline, -the default priomap looks like this: - - 1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1 - -This means that priority 4, for example, gets mapped to band number 1. -The priomap also allows you to list higher priorities (> 7) which do not -correspond to TOS mappings, but which are set by other means. - -This table from RFC 1349 (read it for more details) explains how -applications might very well set their TOS bits: - -.nf -TELNET 1000 (minimize delay) -FTP - Control 1000 (minimize delay) - Data 0100 (maximize throughput) - -TFTP 1000 (minimize delay) - -SMTP - Command phase 1000 (minimize delay) - DATA phase 0100 (maximize throughput) - -Domain Name Service - UDP Query 1000 (minimize delay) - TCP Query 0000 - Zone Transfer 0100 (maximize throughput) - -NNTP 0001 (minimize monetary cost) - -ICMP - Errors 0000 - Requests 0000 (mostly) - Responses <same as request> (mostly) -.fi - - -.SH CLASSES -PRIO classes cannot be configured further - they are automatically created -when the PRIO qdisc is attached. Each class however can contain yet a -further qdisc. - -.SH BUGS -Large amounts of traffic in the lower bands can cause starvation of higher -bands. Can be prevented by attaching a shaper (for example, -.BR tc-tbf(8) -to these bands to make sure they cannot dominate the link. - -.SH AUTHORS -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>, J Hadi Salim -<hadi@cyberus.ca>. This manpage maintained by bert hubert <ahu@ds9a.nl> - - diff --git a/man/man8/tc-red.8 b/man/man8/tc-red.8 deleted file mode 100644 index d02b411..0000000 --- a/man/man8/tc-red.8 +++ /dev/null @@ -1,131 +0,0 @@ -.TH RED 8 "13 December 2001" "iproute2" "Linux" -.SH NAME -red \- Random Early Detection -.SH SYNOPSIS -.B tc qdisc ... red -.B limit -bytes -.B min -bytes -.B max -bytes -.B avpkt -bytes -.B burst -packets -.B [ ecn ] [ bandwidth -rate -.B ] probability -chance - -.SH DESCRIPTION -Random Early Detection is a classless qdisc which manages its queue size -smartly. Regular queues simply drop packets from the tail when they are -full, which may not be the optimal behaviour. RED also performs tail drop, -but does so in a more gradual way. - -Once the queue hits a certain average length, packets enqueued have a -configurable chance of being marked (which may mean dropped). This chance -increases linearly up to a point called the -.B max -average queue length, although the queue might get bigger. - -This has a host of benefits over simple taildrop, while not being processor -intensive. It prevents synchronous retransmits after a burst in traffic, -which cause further retransmits, etc. - -The goal is the have a small queue size, which is good for interactivity -while not disturbing TCP/IP traffic with too many sudden drops after a burst -of traffic. - -Depending on if ECN is configured, marking either means dropping or -purely marking a packet as overlimit. -.SH ALGORITHM -The average queue size is used for determining the marking -probability. This is calculated using an Exponential Weighted Moving -Average, which can be more or less sensitive to bursts. - -When the average queue size is below -.B min -bytes, no packet will ever be marked. When it exceeds -.B min, -the probability of doing so climbs linearly up -to -.B probability, -until the average queue size hits -.B max -bytes. Because -.B probability -is normally not set to 100%, the queue size might -conceivably rise above -.B max -bytes, so the -.B limit -parameter is provided to set a hard maximum for the size of the queue. - -.SH PARAMETERS -.TP -min -Average queue size at which marking becomes a possibility. -.TP -max -At this average queue size, the marking probability is maximal. Should be at -least twice -.B min -to prevent synchronous retransmits, higher for low -.B min. -.TP -probability -Maximum probability for marking, specified as a floating point -number from 0.0 to 1.0. Suggested values are 0.01 or 0.02 (1 or 2%, -respectively). -.TP -limit -Hard limit on the real (not average) queue size in bytes. Further packets -are dropped. Should be set higher than max+burst. It is advised to set this -a few times higher than -.B max. -.TP -burst -Used for determining how fast the average queue size is influenced by the -real queue size. Larger values make the calculation more sluggish, allowing -longer bursts of traffic before marking starts. Real life experiments -support the following guideline: (min+min+max)/(3*avpkt). -.TP -avpkt -Specified in bytes. Used with burst to determine the time constant for -average queue size calculations. 1000 is a good value. -.TP -bandwidth -This rate is used for calculating the average queue size after some -idle time. Should be set to the bandwidth of your interface. Does not mean -that RED will shape for you! Optional. -.TP -ecn -As mentioned before, RED can either 'mark' or 'drop'. Explicit Congestion -Notification allows RED to notify remote hosts that their rate exceeds the -amount of bandwidth available. Non-ECN capable hosts can only be notified by -dropping a packet. If this parameter is specified, packets which indicate -that their hosts honor ECN will only be marked and not dropped, unless the -queue size hits -.B limit -bytes. Needs a tc binary with RED support compiled in. Recommended. - -.SH SEE ALSO -.BR tc (8) - -.SH SOURCES -.TP -o -Floyd, S., and Jacobson, V., Random Early Detection gateways for -Congestion Avoidance. http://www.aciri.org/floyd/papers/red/red.html -.TP -o -Some changes to the algorithm by Alexey N. Kuznetsov. - -.SH AUTHORS -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>, Alexey Makarenko -<makar@phoenix.kharkov.ua>, J Hadi Salim <hadi@nortelnetworks.com>. -This manpage maintained by bert hubert <ahu@ds9a.nl> - - diff --git a/man/man8/tc-sfq.8 b/man/man8/tc-sfq.8 deleted file mode 100644 index 337c795..0000000 --- a/man/man8/tc-sfq.8 +++ /dev/null @@ -1,107 +0,0 @@ -.TH TC 8 "8 December 2001" "iproute2" "Linux" -.SH NAME -sfq \- Stochastic Fairness Queueing -.SH SYNOPSIS -.B tc qdisc ... perturb -seconds -.B quantum -bytes - -.SH DESCRIPTION - -Stochastic Fairness Queueing is a classless queueing discipline available for -traffic control with the -.BR tc (8) -command. - -SFQ does not shape traffic but only schedules the transmission of packets, based on 'flows'. -The goal is to ensure fairness so that each flow is able to send data in turn, thus preventing -any single flow from drowning out the rest. - -This may in fact have some effect in mitigating a Denial of Service attempt. - -SFQ is work-conserving and therefore always delivers a packet if it has one available. -.SH ALGORITHM -On enqueueing, each packet is assigned to a hash bucket, based on -.TP -(i) -Source address -.TP -(ii) -Destination address -.TP -(iii) -Source port -.P -If these are available. SFQ knows about ipv4 and ipv6 and also UDP, TCP and ESP. -Packets with other protocols are hashed based on the 32bits representation of their -destination and the socket they belong to. A flow corresponds mostly to a TCP/IP -connection. - -Each of these buckets should represent a unique flow. Because multiple flows may -get hashed to the same bucket, the hashing algorithm is perturbed at configurable -intervals so that the unfairness lasts only for a short while. Perturbation may -however cause some inadvertent packet reordering to occur. - -When dequeuing, each hashbucket with data is queried in a round robin fashion. - -The compile time maximum length of the SFQ is 128 packets, which can be spread over -at most 128 buckets of 1024 available. In case of overflow, tail-drop is performed -on the fullest bucket, thus maintaining fairness. - -.SH PARAMETERS -.TP -perturb -Interval in seconds for queue algorithm perturbation. Defaults to 0, which means that -no perturbation occurs. Do not set too low for each perturbation may cause some packet -reordering. Advised value: 10 -.TP -quantum -Amount of bytes a flow is allowed to dequeue during a round of the round robin process. -Defaults to the MTU of the interface which is also the advised value and the minimum value. - -.SH EXAMPLE & USAGE - -To attach to device ppp0: -.P -# tc qdisc add dev ppp0 root sfq perturb 10 -.P -Please note that SFQ, like all non-shaping (work-conserving) qdiscs, is only useful -if it owns the queue. -This is the case when the link speed equals the actually available bandwidth. This holds -for regular phone modems, ISDN connections and direct non-switched ethernet links. -.P -Most often, cable modems and DSL devices do not fall into this category. The same holds -for when connected to a switch and trying to send data to a congested segment also -connected to the switch. -.P -In this case, the effective queue does not reside within Linux and is therefore not -available for scheduling. -.P -Embed SFQ in a classful qdisc to make sure it owns the queue. - -.SH SOURCE -.TP -o -Paul E. McKenney "Stochastic Fairness Queuing", -IEEE INFOCOMM'90 Proceedings, San Francisco, 1990. - -.TP -o -Paul E. McKenney "Stochastic Fairness Queuing", -"Interworking: Research and Experience", v.2, 1991, p.113-131. - -.TP -o -See also: -M. Shreedhar and George Varghese "Efficient Fair -Queuing using Deficit Round Robin", Proc. SIGCOMM 95. - -.SH SEE ALSO -.BR tc (8) - -.SH AUTHOR -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>. This manpage maintained by -bert hubert <ahu@ds9a.nl> - - diff --git a/man/man8/tc-tbf.8 b/man/man8/tc-tbf.8 deleted file mode 100644 index 3abb238..0000000 --- a/man/man8/tc-tbf.8 +++ /dev/null @@ -1,138 +0,0 @@ -.TH TC 8 "13 December 2001" "iproute2" "Linux" -.SH NAME -tbf \- Token Bucket Filter -.SH SYNOPSIS -.B tc qdisc ... tbf rate -rate -.B burst -bytes/cell -.B ( latency -ms -.B | limit -bytes -.B ) [ mpu -bytes -.B [ peakrate -rate -.B mtu -bytes/cell -.B ] ] -.P -burst is also known as buffer and maxburst. mtu is also known as minburst. -.SH DESCRIPTION - -The Token Bucket Filter is a classless queueing discipline available for -traffic control with the -.BR tc (8) -command. - -TBF is a pure shaper and never schedules traffic. It is non-work-conserving and may throttle -itself, although packets are available, to ensure that the configured rate is not exceeded. -On all platforms except for Alpha, -it is able to shape up to 1mbit/s of normal traffic with ideal minimal burstiness, -sending out data exactly at the configured rates. - -Much higher rates are possible but at the cost of losing the minimal burstiness. In that -case, data is on average dequeued at the configured rate but may be sent much faster at millisecond -timescales. Because of further queues living in network adaptors, this is often not a problem. - -Kernels with a higher 'HZ' can achieve higher rates with perfect burstiness. On Alpha, HZ is ten -times higher, leading to a 10mbit/s limit to perfection. These calculations hold for packets of on -average 1000 bytes. - -.SH ALGORITHM -As the name implies, traffic is filtered based on the expenditure of -.B tokens. -Tokens roughly correspond to bytes, with the additional constraint that each packet consumes -some tokens, no matter how small it is. This reflects the fact that even a zero-sized packet occupies -the link for some time. - -On creation, the TBF is stocked with tokens which correspond to the amount of traffic that can be burst -in one go. Tokens arrive at a steady rate, until the bucket is full. - -If no tokens are available, packets are queued, up to a configured limit. The TBF now -calculates the token deficit, and throttles until the first packet in the queue can be sent. - -If it is not acceptable to burst out packets at maximum speed, a peakrate can be configured -to limit the speed at which the bucket empties. This peakrate is implemented as a second TBF -with a very small bucket, so that it doesn't burst. - -To achieve perfection, the second bucket may contain only a single packet, which leads to -the earlier mentioned 1mbit/s limit. - -This limit is caused by the fact that the kernel can only throttle for at minimum 1 'jiffy', which depends -on HZ as 1/HZ. For perfect shaping, only a single packet can get sent per jiffy - for HZ=100, this means 100 -packets of on average 1000 bytes each, which roughly corresponds to 1mbit/s. - -.SH PARAMETERS -See -.BR tc (8) -for how to specify the units of these values. -.TP -limit or latency -Limit is the number of bytes that can be queued waiting for tokens to become -available. You can also specify this the other way around by setting the -latency parameter, which specifies the maximum amount of time a packet can -sit in the TBF. The latter calculation takes into account the size of the -bucket, the rate and possibly the peakrate (if set). These two parameters -are mutually exclusive. -.TP -burst -Also known as buffer or maxburst. -Size of the bucket, in bytes. This is the maximum amount of bytes that tokens can be available for instantaneously. -In general, larger shaping rates require a larger buffer. For 10mbit/s on Intel, you need at least 10kbyte buffer -if you want to reach your configured rate! - -If your buffer is too small, packets may be dropped because more tokens arrive per timer tick than fit in your bucket. -The minimum buffer size can be calculated by dividing the rate by HZ. - -Token usage calculations are performed using a table which by default has a resolution of 8 packets. -This resolution can be changed by specifying the -.B cell -size with the burst. For example, to specify a 6000 byte buffer with a 16 -byte cell size, set a burst of 6000/16. You will probably never have to set -this. Must be an integral power of 2. -.TP -mpu -A zero-sized packet does not use zero bandwidth. For ethernet, no packet uses less than 64 bytes. The Minimum Packet Unit -determines the minimal token usage (specified in bytes) for a packet. Defaults to zero. -.TP -rate -The speed knob. See remarks above about limits! See -.BR tc (8) -for units. -.PP -Furthermore, if a peakrate is desired, the following parameters are available: - -.TP -peakrate -Maximum depletion rate of the bucket. Limited to 1mbit/s on Intel, 10mbit/s on Alpha. The peakrate does -not need to be set, it is only necessary if perfect millisecond timescale shaping is required. - -.TP -mtu/minburst -Specifies the size of the peakrate bucket. For perfect accuracy, should be set to the MTU of the interface. -If a peakrate is needed, but some burstiness is acceptable, this size can be raised. A 3000 byte minburst -allows around 3mbit/s of peakrate, given 1000 byte packets. - -Like the regular burstsize you can also specify a -.B cell -size. -.SH EXAMPLE & USAGE - -To attach a TBF with a sustained maximum rate of 0.5mbit/s, a peakrate of 1.0mbit/s, -a 5kilobyte buffer, with a pre-bucket queue size limit calculated so the TBF causes -at most 70ms of latency, with perfect peakrate behaviour, issue: -.P -# tc qdisc add dev eth0 root tbf rate 0.5mbit \\ - burst 5kb latency 70ms peakrate 1mbit \\ - minburst 1540 - -.SH SEE ALSO -.BR tc (8) - -.SH AUTHOR -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>. This manpage maintained by -bert hubert <ahu@ds9a.nl> - - diff --git a/man/man8/tc.8 b/man/man8/tc.8 deleted file mode 100644 index b9b8039..0000000 --- a/man/man8/tc.8 +++ /dev/null @@ -1,348 +0,0 @@ -.TH TC 8 "16 December 2001" "iproute2" "Linux" -.SH NAME -tc \- show / manipulate traffic control settings -.SH SYNOPSIS -.B tc qdisc [ add | change | replace | link ] dev -DEV -.B -[ parent -qdisc-id -.B | root ] -.B [ handle -qdisc-id ] qdisc -[ qdisc specific parameters ] -.P - -.B tc class [ add | change | replace ] dev -DEV -.B parent -qdisc-id -.B [ classid -class-id ] qdisc -[ qdisc specific parameters ] -.P - -.B tc filter [ add | change | replace ] dev -DEV -.B [ parent -qdisc-id -.B | root ] protocol -protocol -.B prio -priority filtertype -[ filtertype specific parameters ] -.B flowid -flow-id - -.B tc [-s | -d ] qdisc show [ dev -DEV -.B ] -.P -.B tc [-s | -d ] class show dev -DEV -.P -.B tc filter show dev -DEV - -.SH DESCRIPTION -.B Tc -is used to configure Traffic Control in the Linux kernel. Traffic Control consists -of the following: - -.TP -SHAPING -When traffic is shaped, its rate of transmission is under control. Shaping may -be more than lowering the available bandwidth - it is also used to smooth out -bursts in traffic for better network behaviour. Shaping occurs on egress. - -.TP -SCHEDULING -By scheduling the transmission of packets it is possible to improve interactivity -for traffic that needs it while still guaranteeing bandwidth to bulk transfers. Reordering -is also called prioritizing, and happens only on egress. - -.TP -POLICING -Where shaping deals with transmission of traffic, policing pertains to traffic -arriving. Policing thus occurs on ingress. - -.TP -DROPPING -Traffic exceeding a set bandwidth may also be dropped forthwith, both on -ingress and on egress. - -.P -Processing of traffic is controlled by three kinds of objects: qdiscs, -classes and filters. - -.SH QDISCS -.B qdisc -is short for 'queueing discipline' and it is elementary to -understanding traffic control. Whenever the kernel needs to send a -packet to an interface, it is -.B enqueued -to the qdisc configured for that interface. Immediately afterwards, the kernel -tries to get as many packets as possible from the qdisc, for giving them -to the network adaptor driver. - -A simple QDISC is the 'pfifo' one, which does no processing at all and is a pure -First In, First Out queue. It does however store traffic when the network interface -can't handle it momentarily. - -.SH CLASSES -Some qdiscs can contain classes, which contain further qdiscs - traffic may -then be enqueued in any of the inner qdiscs, which are within the -.B classes. -When the kernel tries to dequeue a packet from such a -.B classful qdisc -it can come from any of the classes. A qdisc may for example prioritize -certain kinds of traffic by trying to dequeue from certain classes -before others. - -.SH FILTERS -A -.B filter -is used by a classful qdisc to determine in which class a packet will -be enqueued. Whenever traffic arrives at a class with subclasses, it needs -to be classified. Various methods may be employed to do so, one of these -are the filters. All filters attached to the class are called, until one of -them returns with a verdict. If no verdict was made, other criteria may be -available. This differs per qdisc. - -It is important to notice that filters reside -.B within -qdiscs - they are not masters of what happens. - -.SH CLASSLESS QDISCS -The classless qdiscs are: -.TP -[p|b]fifo -Simplest usable qdisc, pure First In, First Out behaviour. Limited in -packets or in bytes. -.TP -pfifo_fast -Standard qdisc for 'Advanced Router' enabled kernels. Consists of a three-band -queue which honors Type of Service flags, as well as the priority that may be -assigned to a packet. -.TP -red -Random Early Detection simulates physical congestion by randomly dropping -packets when nearing configured bandwidth allocation. Well suited to very -large bandwidth applications. -.TP -sfq -Stochastic Fairness Queueing reorders queued traffic so each 'session' -gets to send a packet in turn. -.TP -tbf -The Token Bucket Filter is suited for slowing traffic down to a precisely -configured rate. Scales well to large bandwidths. -.SH CONFIGURING CLASSLESS QDISCS -In the absence of classful qdiscs, classless qdiscs can only be attached at -the root of a device. Full syntax: -.P -.B tc qdisc add dev -DEV -.B root -QDISC QDISC-PARAMETERS - -To remove, issue -.P -.B tc qdisc del dev -DEV -.B root - -The -.B pfifo_fast -qdisc is the automatic default in the absence of a configured qdisc. - -.SH CLASSFUL QDISCS -The classful qdiscs are: -.TP -CBQ -Class Based Queueing implements a rich linksharing hierarchy of classes. -It contains shaping elements as well as prioritizing capabilities. Shaping is -performed using link idle time calculations based on average packet size and -underlying link bandwidth. The latter may be ill-defined for some interfaces. -.TP -HTB -The Hierarchy Token Bucket implements a rich linksharing hierarchy of -classes with an emphasis on conforming to existing practices. HTB facilitates -guaranteeing bandwidth to classes, while also allowing specification of upper -limits to inter-class sharing. It contains shaping elements, based on TBF and -can prioritize classes. -.TP -PRIO -The PRIO qdisc is a non-shaping container for a configurable number of -classes which are dequeued in order. This allows for easy prioritization -of traffic, where lower classes are only able to send if higher ones have -no packets available. To facilitate configuration, Type Of Service bits are -honored by default. -.SH THEORY OF OPERATION -Classes form a tree, where each class has a single parent. -A class may have multiple children. Some qdiscs allow for runtime addition -of classes (CBQ, HTB) while others (PRIO) are created with a static number of -children. - -Qdiscs which allow dynamic addition of classes can have zero or more -subclasses to which traffic may be enqueued. - -Furthermore, each class contains a -.B leaf qdisc -which by default has -.B pfifo -behaviour though another qdisc can be attached in place. This qdisc may again -contain classes, but each class can have only one leaf qdisc. - -When a packet enters a classful qdisc it can be -.B classified -to one of the classes within. Three criteria are available, although not all -qdiscs will use all three: -.TP -tc filters -If tc filters are attached to a class, they are consulted first -for relevant instructions. Filters can match on all fields of a packet header, -as well as on the firewall mark applied by ipchains or iptables. See -.BR tc-filters (8). -.TP -Type of Service -Some qdiscs have built in rules for classifying packets based on the TOS field. -.TP -skb->priority -Userspace programs can encode a class-id in the 'skb->priority' field using -the SO_PRIORITY option. -.P -Each node within the tree can have its own filters but higher level filters -may also point directly to lower classes. - -If classification did not succeed, packets are enqueued to the leaf qdisc -attached to that class. Check qdisc specific manpages for details, however. - -.SH NAMING -All qdiscs, classes and filters have IDs, which can either be specified -or be automatically assigned. - -IDs consist of a major number and a minor number, separated by a colon. - -.TP -QDISCS -A qdisc, which potentially can have children, -gets assigned a major number, called a 'handle', leaving the minor -number namespace available for classes. The handle is expressed as '10:'. -It is customary to explicitly assign a handle to qdiscs expected to have -children. - -.TP -CLASSES -Classes residing under a qdisc share their qdisc major number, but each have -a separate minor number called a 'classid' that has no relation to their -parent classes, only to their parent qdisc. The same naming custom as for -qdiscs applies. - -.TP -FILTERS -Filters have a three part ID, which is only needed when using a hashed -filter hierarchy, for which see -.BR tc-filters (8). -.SH UNITS -All parameters accept a floating point number, possibly followed by a unit. -.P -Bandwidths or rates can be specified in: -.TP -kbps -Kilobytes per second -.TP -mbps -Megabytes per second -.TP -kbit -Kilobits per second -.TP -mbit -Megabits per second -.TP -bps or a bare number -Bytes per second -.P -Amounts of data can be specified in: -.TP -kb or k -Kilobytes -.TP -mb or m -Megabytes -.TP -mbit -Megabits -.TP -kbit -Kilobits -.TP -b or a bare number -Bytes. -.P -Lengths of time can be specified in: -.TP -s, sec or secs -Whole seconds -.TP -ms, msec or msecs -Milliseconds -.TP -us, usec, usecs or a bare number -Microseconds. - -.SH TC COMMANDS -The following commands are available for qdiscs, classes and filter: -.TP -add -Add a qdisc, class or filter to a node. For all entities, a -.B parent -must be passed, either by passing its ID or by attaching directly to the root of a device. -When creating a qdisc or a filter, it can be named with the -.B handle -parameter. A class is named with the -.B classid -parameter. - -.TP -remove -A qdisc can be removed by specifying its handle, which may also be 'root'. All subclasses and their leaf qdiscs -are automatically deleted, as well as any filters attached to them. - -.TP -change -Some entities can be modified 'in place'. Shares the syntax of 'add', with the exception -that the handle cannot be changed and neither can the parent. In other words, -.B -change -cannot move a node. - -.TP -replace -Performs a nearly atomic remove/add on an existing node id. If the node does not exist yet -it is created. - -.TP -link -Only available for qdiscs and performs a replace where the node -must exist already. - - -.SH HISTORY -.B tc -was written by Alexey N. Kuznetsov and added in Linux 2.2. -.SH SEE ALSO -.BR tc-cbq (8), -.BR tc-htb (8), -.BR tc-sfq (8), -.BR tc-red (8), -.BR tc-tbf (8), -.BR tc-pfifo (8), -.BR tc-bfifo (8), -.BR tc-pfifo_fast (8), -.BR tc-filters (8) - -.SH AUTHOR -Manpage maintained by bert hubert (ahu@ds9a.nl) - diff --git a/misc/Makefile b/misc/Makefile deleted file mode 100644 index bda37e5..0000000 --- a/misc/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -SSOBJ=ss.o ssfilter.o -LNSTATOBJ=lnstat.o lnstat_util.o - -TARGETS=ss nstat ifstat rtacct arpd lnstat - -include ../Config - -all: $(TARGETS) - -ss: $(SSOBJ) $(LIBUTIL) - -nstat: nstat.c - $(CC) $(CFLAGS) $(LDFLAGS) -o nstat nstat.c -lm - -ifstat: ifstat.c - $(CC) $(CFLAGS) $(LDFLAGS) -o ifstat ifstat.c $(LIBNETLINK) -lm - -rtacct: rtacct.c - $(CC) $(CFLAGS) $(LDFLAGS) -o rtacct rtacct.c $(LIBNETLINK) -lm - -arpd: arpd.c - $(CC) $(CFLAGS) -I$(DBM_INCLUDE) $(LDFLAGS) -o arpd arpd.c $(LIBNETLINK) -ldb -lpthread - -ssfilter.c: ssfilter.y - bison ssfilter.y -o ssfilter.c - -lnstat: $(LNSTATOBJ) - -install: all - install -m 0755 -s $(TARGETS) $(DESTDIR)$(SBINDIR) - ln -sf lnstat $(DESTDIR)$(SBINDIR)/rtstat - ln -sf lnstat $(DESTDIR)$(SBINDIR)/ctstat - -clean: - rm -f *.o $(TARGETS) ssfilter.c diff --git a/misc/arpd.c b/misc/arpd.c deleted file mode 100644 index 4fd226e..0000000 --- a/misc/arpd.c +++ /dev/null @@ -1,847 +0,0 @@ -/* - * arpd.c ARP helper daemon. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - */ - -#include <stdio.h> -#include <syslog.h> -#include <malloc.h> -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <netdb.h> -#include <db_185.h> -#include <sys/ioctl.h> -#include <sys/poll.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <time.h> -#include <signal.h> -#include <linux/if.h> -#include <linux/if_ether.h> -#include <linux/if_arp.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <linux/if_packet.h> -#include <linux/filter.h> - -#include "libnetlink.h" -#include "utils.h" - -int resolve_hosts; - -DB *dbase; -char *dbname = "/var/lib/arpd/arpd.db"; - -int ifnum; -int *ifvec; -char **ifnames; - -struct dbkey -{ - __u32 iface; - __u32 addr; -}; - -#define IS_NEG(x) (((__u8*)(x))[0] == 0xFF) -#define NEG_TIME(x) (((x)[2]<<24)|((x)[3]<<16)|((x)[4]<<8)|(x)[5]) -#define NEG_AGE(x) ((__u32)time(NULL) - NEG_TIME((__u8*)x)) -#define NEG_VALID(x) (NEG_AGE(x) < negative_timeout) -#define NEG_CNT(x) (((__u8*)(x))[1]) - -struct rtnl_handle rth; - -struct pollfd pset[2]; -int udp_sock = -1; - -volatile int do_exit; -volatile int do_sync; -volatile int do_stats; - -struct { - unsigned long arp_new; - unsigned long arp_change; - - unsigned long app_recv; - unsigned long app_success; - unsigned long app_bad; - unsigned long app_neg; - unsigned long app_suppressed; - - unsigned long kern_neg; - unsigned long kern_new; - unsigned long kern_change; - - unsigned long probes_sent; - unsigned long probes_suppressed; -} stats; - -int active_probing; -int negative_timeout = 60; -int no_kernel_broadcasts; -int broadcast_rate = 1000; -int broadcast_burst = 3000; - -void usage(void) -{ - fprintf(stderr, -"Usage: arpd [ -lk ] [ -a N ] [ -b dbase ] [ -f file ] [ interfaces ]\n"); - exit(1); -} - -int handle_if(int ifindex) -{ - int i; - - if (ifnum == 0) - return 1; - - for (i=0; i<ifnum; i++) - if (ifvec[i] == ifindex) - return 1; - return 0; -} - -int sysctl_adjusted; - -void do_sysctl_adjustments(void) -{ - int i; - - if (!ifnum) - return; - - for (i=0; i<ifnum; i++) { - char buf[128]; - FILE *fp; - - if (active_probing) { - sprintf(buf, "/proc/sys/net/ipv4/neigh/%s/mcast_solicit", ifnames[i]); - if ((fp = fopen(buf, "w")) != NULL) { - if (no_kernel_broadcasts) - strcpy(buf, "0\n"); - else - sprintf(buf, "%d\n", active_probing>=2 ? 1 : 3-active_probing); - fputs(buf, fp); - fclose(fp); - } - } - - sprintf(buf, "/proc/sys/net/ipv4/neigh/%s/app_solicit", ifnames[i]); - if ((fp = fopen(buf, "w")) != NULL) { - sprintf(buf, "%d\n", active_probing<=1 ? 1 : active_probing); - fputs(buf, fp); - fclose(fp); - } - } - sysctl_adjusted = 1; -} - -void undo_sysctl_adjustments(void) -{ - int i; - - if (!sysctl_adjusted) - return; - - for (i=0; i<ifnum; i++) { - char buf[128]; - FILE *fp; - - if (active_probing) { - sprintf(buf, "/proc/sys/net/ipv4/neigh/%s/mcast_solicit", ifnames[i]); - if ((fp = fopen(buf, "w")) != NULL) { - strcpy(buf, "3\n"); - fputs(buf, fp); - fclose(fp); - } - } - sprintf(buf, "/proc/sys/net/ipv4/neigh/%s/app_solicit", ifnames[i]); - if ((fp = fopen(buf, "w")) != NULL) { - strcpy(buf, "0\n"); - fputs(buf, fp); - fclose(fp); - } - } - sysctl_adjusted = 0; -} - - -int send_probe(int ifindex, __u32 addr) -{ - struct ifreq ifr; - struct sockaddr_in dst; - socklen_t len; - unsigned char buf[256]; - struct arphdr *ah = (struct arphdr*)buf; - unsigned char *p = (unsigned char *)(ah+1); - struct sockaddr_ll sll; - - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_ifindex = ifindex; - if (ioctl(udp_sock, SIOCGIFNAME, &ifr)) - return -1; - if (ioctl(udp_sock, SIOCGIFHWADDR, &ifr)) - return -1; - if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) - return -1; - if (setsockopt(udp_sock, SOL_SOCKET, SO_BINDTODEVICE, ifr.ifr_name, strlen(ifr.ifr_name)+1) < 0) - return -1; - - dst.sin_family = AF_INET; - dst.sin_port = htons(1025); - dst.sin_addr.s_addr = addr; - if (connect(udp_sock, (struct sockaddr*)&dst, sizeof(dst)) < 0) - return -1; - len = sizeof(dst); - if (getsockname(udp_sock, (struct sockaddr*)&dst, &len) < 0) - return -1; - - ah->ar_hrd = htons(ifr.ifr_hwaddr.sa_family); - ah->ar_pro = htons(ETH_P_IP); - ah->ar_hln = 6; - ah->ar_pln = 4; - ah->ar_op = htons(ARPOP_REQUEST); - - memcpy(p, ifr.ifr_hwaddr.sa_data, ah->ar_hln); - p += ah->ar_hln; - - memcpy(p, &dst.sin_addr, 4); - p+=4; - - sll.sll_family = AF_PACKET; - memset(sll.sll_addr, 0xFF, sizeof(sll.sll_addr)); - sll.sll_ifindex = ifindex; - sll.sll_protocol = htons(ETH_P_ARP); - memcpy(p, &sll.sll_addr, ah->ar_hln); - p+=ah->ar_hln; - - memcpy(p, &addr, 4); - p+=4; - - if (sendto(pset[0].fd, buf, p-buf, 0, (struct sockaddr*)&sll, sizeof(sll)) < 0) - return -1; - stats.probes_sent++; - return 0; -} - -/* Be very tough on sending probes: 1 per second with burst of 3. */ - -int queue_active_probe(int ifindex, __u32 addr) -{ - static struct timeval prev; - static int buckets; - struct timeval now; - - gettimeofday(&now, NULL); - if (prev.tv_sec) { - int diff = (now.tv_sec-prev.tv_sec)*1000+(now.tv_usec-prev.tv_usec)/1000; - buckets += diff; - } else { - buckets = broadcast_burst; - } - if (buckets > broadcast_burst) - buckets = broadcast_burst; - if (buckets >= broadcast_rate && !send_probe(ifindex, addr)) { - buckets -= broadcast_rate; - prev = now; - return 0; - } - stats.probes_suppressed++; - return -1; -} - -int respond_to_kernel(int ifindex, __u32 addr, char *lla, int llalen) -{ - struct { - struct nlmsghdr n; - struct ndmsg ndm; - char buf[256]; - } req; - - memset(&req.n, 0, sizeof(req.n)); - memset(&req.ndm, 0, sizeof(req.ndm)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST; - req.n.nlmsg_type = RTM_NEWNEIGH; - req.ndm.ndm_family = AF_INET; - req.ndm.ndm_state = NUD_STALE; - req.ndm.ndm_ifindex = ifindex; - req.ndm.ndm_type = RTN_UNICAST; - - addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4); - addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen); - return rtnl_send(&rth, (char*)&req, req.n.nlmsg_len) <= 0; -} - -void prepare_neg_entry(__u8 *ndata, __u32 stamp) -{ - ndata[0] = 0xFF; - ndata[1] = 0; - ndata[2] = stamp>>24; - ndata[3] = stamp>>16; - ndata[4] = stamp>>8; - ndata[5] = stamp; -} - - -int do_one_request(struct nlmsghdr *n) -{ - struct ndmsg *ndm = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr * tb[NDA_MAX+1]; - struct dbkey key; - DBT dbkey, dbdat; - int do_acct = 0; - - if (n->nlmsg_type == NLMSG_DONE) { - dbase->sync(dbase, 0); - - /* Now we have at least mirror of kernel db, so that - * may start real resolution. - */ - do_sysctl_adjustments(); - return 0; - } - - if (n->nlmsg_type != RTM_GETNEIGH && n->nlmsg_type != RTM_NEWNEIGH) - return 0; - - len -= NLMSG_LENGTH(sizeof(*ndm)); - if (len < 0) - return -1; - - if (ndm->ndm_family != AF_INET || - (ifnum && !handle_if(ndm->ndm_ifindex)) || - ndm->ndm_flags || - ndm->ndm_type != RTN_UNICAST || - !(ndm->ndm_state&~NUD_NOARP)) - return 0; - - parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len); - - if (!tb[NDA_DST]) - return 0; - - key.iface = ndm->ndm_ifindex; - memcpy(&key.addr, RTA_DATA(tb[NDA_DST]), 4); - dbkey.data = &key; - dbkey.size = sizeof(key); - - if (dbase->get(dbase, &dbkey, &dbdat, 0) != 0) { - dbdat.data = 0; - dbdat.size = 0; - } - - if (n->nlmsg_type == RTM_GETNEIGH) { - if (!(n->nlmsg_flags&NLM_F_REQUEST)) - return 0; - - if (!(ndm->ndm_state&(NUD_PROBE|NUD_INCOMPLETE))) { - stats.app_bad++; - return 0; - } - - if (ndm->ndm_state&NUD_PROBE) { - /* If we get this, kernel still has some valid - * address, but unicast probing failed and host - * is either dead or changed its mac address. - * Kernel is going to initiate broadcast resolution. - * OK, we invalidate our information as well. - */ - if (dbdat.data && !IS_NEG(dbdat.data)) - stats.app_neg++; - - dbase->del(dbase, &dbkey, 0); - } else { - /* If we get this kernel does not have any information. - * If we have something tell this to kernel. */ - stats.app_recv++; - if (dbdat.data && !IS_NEG(dbdat.data)) { - stats.app_success++; - respond_to_kernel(key.iface, key.addr, dbdat.data, dbdat.size); - return 0; - } - - /* Sheeit! We have nothing to tell. */ - /* If we have recent negative entry, be silent. */ - if (dbdat.data && NEG_VALID(dbdat.data)) { - if (NEG_CNT(dbdat.data) >= active_probing) { - stats.app_suppressed++; - return 0; - } - do_acct = 1; - } - } - - if (active_probing && - queue_active_probe(ndm->ndm_ifindex, key.addr) == 0 && - do_acct) { - NEG_CNT(dbdat.data)++; - dbase->put(dbase, &dbkey, &dbdat, 0); - } - } else if (n->nlmsg_type == RTM_NEWNEIGH) { - if (n->nlmsg_flags&NLM_F_REQUEST) - return 0; - - if (ndm->ndm_state&NUD_FAILED) { - /* Kernel was not able to resolve. Host is dead. - * Create negative entry if it is not present - * or renew it if it is too old. */ - if (!dbdat.data || - !IS_NEG(dbdat.data) || - !NEG_VALID(dbdat.data)) { - __u8 ndata[6]; - stats.kern_neg++; - prepare_neg_entry(ndata, time(NULL)); - dbdat.data = ndata; - dbdat.size = sizeof(ndata); - dbase->put(dbase, &dbkey, &dbdat, 0); - } - } else if (tb[NDA_LLADDR]) { - if (dbdat.data && !IS_NEG(dbdat.data)) { - if (memcmp(RTA_DATA(tb[NDA_LLADDR]), dbdat.data, dbdat.size) == 0) - return 0; - stats.kern_change++; - } else { - stats.kern_new++; - } - dbdat.data = RTA_DATA(tb[NDA_LLADDR]); - dbdat.size = RTA_PAYLOAD(tb[NDA_LLADDR]); - dbase->put(dbase, &dbkey, &dbdat, 0); - } - } - return 0; -} - -void load_initial_table(void) -{ - rtnl_wilddump_request(&rth, AF_INET, RTM_GETNEIGH); -} - -void get_kern_msg(void) -{ - int status; - struct nlmsghdr *h; - struct sockaddr_nl nladdr; - struct iovec iov; - char buf[8192]; - struct msghdr msg = { - (void*)&nladdr, sizeof(nladdr), - &iov, 1, - NULL, 0, - 0 - }; - - memset(&nladdr, 0, sizeof(nladdr)); - - iov.iov_base = buf; - iov.iov_len = sizeof(buf); - - status = recvmsg(rth.fd, &msg, MSG_DONTWAIT); - - if (status <= 0) - return; - - if (msg.msg_namelen != sizeof(nladdr)) - return; - - if (nladdr.nl_pid) - return; - - for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) { - int len = h->nlmsg_len; - int l = len - sizeof(*h); - - if (l < 0 || len > status) - return; - - if (do_one_request(h) < 0) - return; - - status -= NLMSG_ALIGN(len); - h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); - } -} - -/* Receive gratuitous ARP messages and store them, that's all. */ -void get_arp_pkt(void) -{ - unsigned char buf[1024]; - struct sockaddr_ll sll; - socklen_t sll_len = sizeof(sll); - struct arphdr *a = (struct arphdr*)buf; - struct dbkey key; - DBT dbkey, dbdat; - int n; - - n = recvfrom(pset[0].fd, buf, sizeof(buf), MSG_DONTWAIT, - (struct sockaddr*)&sll, &sll_len); - if (n < 0) { - if (errno != EINTR && errno != EAGAIN) - syslog(LOG_ERR, "recvfrom: %m"); - return; - } - - if (ifnum && !handle_if(sll.sll_ifindex)) - return; - - /* Sanity checks */ - - if (n < sizeof(*a) || - (a->ar_op != htons(ARPOP_REQUEST) && - a->ar_op != htons(ARPOP_REPLY)) || - a->ar_pln != 4 || - a->ar_pro != htons(ETH_P_IP) || - a->ar_hln != sll.sll_halen || - sizeof(*a) + 2*4 + 2*a->ar_hln > n) - return; - - key.iface = sll.sll_ifindex; - memcpy(&key.addr, (char*)(a+1) + a->ar_hln, 4); - - /* DAD message, ignore. */ - if (key.addr == 0) - return; - - dbkey.data = &key; - dbkey.size = sizeof(key); - - if (dbase->get(dbase, &dbkey, &dbdat, 0) == 0 && !IS_NEG(dbdat.data)) { - if (memcmp(dbdat.data, a+1, dbdat.size) == 0) - return; - stats.arp_change++; - } else { - stats.arp_new++; - } - - dbdat.data = a+1; - dbdat.size = a->ar_hln; - dbase->put(dbase, &dbkey, &dbdat, 0); -} - -void catch_signal(int sig, void (*handler)(int)) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = handler; -#ifdef SA_INTERRUPT - sa.sa_flags = SA_INTERRUPT; -#endif - sigaction(sig, &sa, NULL); -} - -#include <setjmp.h> -sigjmp_buf env; -volatile int in_poll; - -void sig_exit(int signo) -{ - do_exit = 1; - if (in_poll) - siglongjmp(env, 1); -} - -void sig_sync(int signo) -{ - do_sync = 1; - if (in_poll) - siglongjmp(env, 1); -} - -void sig_stats(int signo) -{ - do_sync = 1; - do_stats = 1; - if (in_poll) - siglongjmp(env, 1); -} - -void send_stats(void) -{ - syslog(LOG_INFO, "arp_rcv: n%lu c%lu app_rcv: tot %lu hits %lu bad %lu neg %lu sup %lu", - stats.arp_new, stats.arp_change, - - stats.app_recv, stats.app_success, - stats.app_bad, stats.app_neg, stats.app_suppressed - ); - syslog(LOG_INFO, "kern: n%lu c%lu neg %lu arp_send: %lu rlim %lu", - stats.kern_new, stats.kern_change, stats.kern_neg, - - stats.probes_sent, stats.probes_suppressed - ); - do_stats = 0; -} - - -int main(int argc, char **argv) -{ - int opt; - int do_list = 0; - char *do_load = NULL; - - while ((opt = getopt(argc, argv, "h?b:lf:a:n:kR:B:")) != EOF) { - switch (opt) { - case 'b': - dbname = optarg; - break; - case 'f': - if (do_load) { - fprintf(stderr, "Duplicate option -f\n"); - usage(); - } - do_load = optarg; - break; - case 'l': - do_list = 1; - break; - case 'a': - active_probing = atoi(optarg); - break; - case 'n': - negative_timeout = atoi(optarg); - break; - case 'k': - no_kernel_broadcasts = 1; - break; - case 'R': - if ((broadcast_rate = atoi(optarg)) <= 0 || - (broadcast_rate = 1000/broadcast_rate) <= 0) { - fprintf(stderr, "Invalid ARP rate\n"); - exit(-1); - } - break; - case 'B': - if ((broadcast_burst = atoi(optarg)) <= 0 || - (broadcast_burst = 1000*broadcast_burst) <= 0) { - fprintf(stderr, "Invalid ARP burst\n"); - exit(-1); - } - break; - case 'h': - case '?': - default: - usage(); - } - } - argc -= optind; - argv += optind; - - if (argc > 0) { - ifnum = argc; - ifnames = argv; - ifvec = malloc(argc*sizeof(int)); - if (!ifvec) { - perror("malloc"); - exit(-1); - } - } - - if ((udp_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("socket"); - exit(-1); - } - - if (ifnum) { - int i; - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - for (i=0; i<ifnum; i++) { - strncpy(ifr.ifr_name, ifnames[i], IFNAMSIZ); - if (ioctl(udp_sock, SIOCGIFINDEX, &ifr)) { - perror("ioctl(SIOCGIFINDEX)"); - exit(-1);; - } - ifvec[i] = ifr.ifr_ifindex; - } - } - - dbase = dbopen(dbname, O_CREAT|O_RDWR, 0644, DB_HASH, NULL); - if (dbase == NULL) { - perror("db_open"); - exit(-1); - } - - if (do_load) { - char buf[128]; - FILE *fp; - struct dbkey k; - DBT dbkey, dbdat; - - dbkey.data = &k; - dbkey.size = sizeof(k); - - if (strcmp(do_load, "-") == 0 || strcmp(do_load, "--") == 0) { - fp = stdin; - } else if ((fp = fopen(do_load, "r")) == NULL) { - perror("fopen"); - goto do_abort; - } - - buf[sizeof(buf)-1] = 0; - while (fgets(buf, sizeof(buf)-1, fp)) { - __u8 b1[6]; - char ipbuf[128]; - char macbuf[128]; - - if (buf[0] == '#') - continue; - - if (sscanf(buf, "%u%s%s", &k.iface, ipbuf, macbuf) != 3) { - fprintf(stderr, "Wrong format of input file \"%s\"\n", do_load); - goto do_abort; - } - if (strncmp(macbuf, "FAILED:", 7) == 0) - continue; - if (!inet_aton(ipbuf, (struct in_addr*)&k.addr)) { - fprintf(stderr, "Invalid IP address: \"%s\"\n", ipbuf); - goto do_abort; - } - - dbdat.data = hexstring_a2n(macbuf, b1, 6); - if (dbdat.data == NULL) - goto do_abort; - dbdat.size = 6; - - if (dbase->put(dbase, &dbkey, &dbdat, 0)) { - perror("hash->put"); - goto do_abort; - } - } - dbase->sync(dbase, 0); - if (fp != stdin) - fclose(fp); - } - - if (do_list) { - DBT dbkey, dbdat; - printf("%-8s %-15s %s\n", "#Ifindex", "IP", "MAC"); - while (dbase->seq(dbase, &dbkey, &dbdat, R_NEXT) == 0) { - struct dbkey *key = dbkey.data; - if (handle_if(key->iface)) { - if (!IS_NEG(dbdat.data)) { - char b1[18]; - printf("%-8d %-15s %s\n", - key->iface, - inet_ntoa(*(struct in_addr*)&key->addr), - hexstring_n2a(dbdat.data, 6, b1, 18)); - } else { - printf("%-8d %-15s FAILED: %dsec ago\n", - key->iface, - inet_ntoa(*(struct in_addr*)&key->addr), - NEG_AGE(dbdat.data)); - } - } - } - } - - if (do_load || do_list) - goto out; - - pset[0].fd = socket(PF_PACKET, SOCK_DGRAM, 0); - if (pset[0].fd < 0) { - perror("socket"); - exit(-1); - } - - if (1) { - struct sockaddr_ll sll; - memset(&sll, 0, sizeof(sll)); - sll.sll_family = AF_PACKET; - sll.sll_protocol = htons(ETH_P_ARP); - sll.sll_ifindex = (ifnum == 1 ? ifvec[0] : 0); - if (bind(pset[0].fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) { - perror("bind"); - goto do_abort; - } - } - - if (rtnl_open(&rth, RTMGRP_NEIGH) < 0) { - perror("rtnl_open"); - goto do_abort; - } - pset[1].fd = rth.fd; - - load_initial_table(); - - if (1) { - int fd; - pid_t pid = fork(); - - if (pid > 0) - _exit(0); - if (pid < 0) { - perror("arpd: fork"); - goto do_abort; - } - - chdir("/"); - fd = open("/dev/null", O_RDWR); - if (fd >= 0) { - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - if (fd > 2) - close(fd); - } - setsid(); - } - - openlog("arpd", LOG_PID | LOG_CONS, LOG_DAEMON); - catch_signal(SIGINT, sig_exit); - catch_signal(SIGTERM, sig_exit); - catch_signal(SIGHUP, sig_sync); - catch_signal(SIGUSR1, sig_stats); - -#define EVENTS (POLLIN|POLLPRI|POLLERR|POLLHUP) - pset[0].events = EVENTS; - pset[0].revents = 0; - pset[1].events = EVENTS; - pset[1].revents = 0; - - sigsetjmp(env, 1); - - for (;;) { - in_poll = 1; - - if (do_exit) - break; - if (do_sync) { - in_poll = 0; - dbase->sync(dbase, 0); - do_sync = 0; - in_poll = 1; - } - if (do_stats) - send_stats(); - if (poll(pset, 2, 30000) > 0) { - in_poll = 0; - if (pset[0].revents&EVENTS) - get_arp_pkt(); - if (pset[1].revents&EVENTS) - get_kern_msg(); - } else { - do_sync = 1; - } - } - - undo_sysctl_adjustments(); -out: - dbase->close(dbase); - exit(0); - -do_abort: - dbase->close(dbase); - exit(-1); -} diff --git a/misc/ifstat.c b/misc/ifstat.c deleted file mode 100644 index 4b87994..0000000 --- a/misc/ifstat.c +++ /dev/null @@ -1,769 +0,0 @@ -/* - * ifstat.c handy utility to read net interface statistics - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <sys/time.h> -#include <fnmatch.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/poll.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <signal.h> -#include <math.h> -#include <getopt.h> - -#include <libnetlink.h> -#include <linux/netdevice.h> - -#include <SNAPSHOT.h> - -int dump_zeros = 0; -int reset_history = 0; -int ignore_history = 0; -int no_output = 0; -int no_update = 0; -int scan_interval = 0; -int time_constant = 0; -int show_errors = 0; -double W; -char **patterns; -int npatterns; - -char info_source[128]; -int source_mismatch; - -#define MAXS (sizeof(struct net_device_stats)/sizeof(unsigned long)) - -struct ifstat_ent -{ - struct ifstat_ent *next; - char *name; - int ifindex; - unsigned long long val[MAXS]; - double rate[MAXS]; - unsigned long ival[MAXS]; -}; - -struct ifstat_ent *kern_db; -struct ifstat_ent *hist_db; - -static int match(const char *id) -{ - int i; - - if (npatterns == 0) - return 1; - - for (i=0; i<npatterns; i++) { - if (!fnmatch(patterns[i], id, 0)) - return 1; - } - return 0; -} - -static int get_nlmsg(const struct sockaddr_nl *who, - struct nlmsghdr *m, void *arg) -{ - struct ifinfomsg *ifi = NLMSG_DATA(m); - struct rtattr * tb[IFLA_MAX+1]; - int len = m->nlmsg_len; - struct ifstat_ent *n; - int i; - - if (m->nlmsg_type != RTM_NEWLINK) - return 0; - - len -= NLMSG_LENGTH(sizeof(*ifi)); - if (len < 0) - return -1; - - if (!(ifi->ifi_flags&IFF_UP)) - return 0; - - parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); - if (tb[IFLA_IFNAME] == NULL || tb[IFLA_STATS] == NULL) - return 0; - - n = malloc(sizeof(*n)); - if (!n) - abort(); - n->ifindex = ifi->ifi_index; - n->name = strdup(RTA_DATA(tb[IFLA_IFNAME])); - memcpy(&n->ival, RTA_DATA(tb[IFLA_STATS]), sizeof(n->ival)); - memset(&n->rate, 0, sizeof(n->rate)); - for (i=0; i<MAXS; i++) - n->val[i] = n->ival[i]; - n->next = kern_db; - kern_db = n; - return 0; -} - -void load_info(void) -{ - struct ifstat_ent *db, *n; - struct rtnl_handle rth; - - if (rtnl_open(&rth, 0) < 0) - exit(1); - - if (rtnl_wilddump_request(&rth, AF_INET, RTM_GETLINK) < 0) { - perror("Cannot send dump request"); - exit(1); - } - - if (rtnl_dump_filter(&rth, get_nlmsg, NULL, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - exit(1); - } - - rtnl_close(&rth); - - db = kern_db; - kern_db = NULL; - - while (db) { - n = db; - db = db->next; - n->next = kern_db; - kern_db = n; - } -} - -void load_raw_table(FILE *fp) -{ - char buf[4096]; - struct ifstat_ent *db = NULL; - struct ifstat_ent *n; - - while (fgets(buf, sizeof(buf), fp) != NULL) { - char *p; - char *next; - int i; - - if (buf[0] == '#') { - buf[strlen(buf)-1] = 0; - if (info_source[0] && strcmp(info_source, buf+1)) - source_mismatch = 1; - strncpy(info_source, buf+1, sizeof(info_source)-1); - continue; - } - if ((n = malloc(sizeof(*n))) == NULL) - abort(); - - if (!(p = strchr(buf, ' '))) - abort(); - *p++ = 0; - - if (sscanf(buf, "%d", &n->ifindex) != 1) - abort(); - if (!(next = strchr(p, ' '))) - abort(); - *next++ = 0; - - n->name = strdup(p); - p = next; - - for (i=0; i<MAXS; i++) { - unsigned rate; - if (!(next = strchr(p, ' '))) - abort(); - *next++ = 0; - if (sscanf(p, "%llu", n->val+i) != 1) - abort(); - n->ival[i] = (unsigned long)n->val[i]; - p = next; - if (!(next = strchr(p, ' '))) - abort(); - *next++ = 0; - if (sscanf(p, "%u", &rate) != 1) - abort(); - n->rate[i] = rate; - p = next; - } - n->next = db; - db = n; - } - - while (db) { - n = db; - db = db->next; - n->next = kern_db; - kern_db = n; - } -} - -void dump_raw_db(FILE *fp, int to_hist) -{ - struct ifstat_ent *n, *h; - h = hist_db; - fprintf(fp, "#%s\n", info_source); - - for (n=kern_db; n; n=n->next) { - int i; - unsigned long long *vals = n->val; - double *rates = n->rate; - if (!match(n->name)) { - struct ifstat_ent *h1; - if (!to_hist) - continue; - for (h1 = h; h1; h1 = h1->next) { - if (h1->ifindex == n->ifindex) { - vals = h1->val; - rates = h1->rate; - h = h1->next; - break; - } - } - } - fprintf(fp, "%d %s ", n->ifindex, n->name); - for (i=0; i<MAXS; i++) - fprintf(fp, "%llu %u ", vals[i], (unsigned)rates[i]); - fprintf(fp, "\n"); - } -} - -/* use communication definitions of meg/kilo etc */ -static const unsigned long long giga = 1000000000ull; -static const unsigned long long mega = 1000000; -static const unsigned long long kilo = 1000; - -void format_rate(FILE *fp, unsigned long long *vals, double *rates, int i) -{ - char temp[64]; - if (vals[i] > giga) - fprintf(fp, "%7lluM ", vals[i]/mega); - else if (vals[i] > mega) - fprintf(fp, "%7lluK ", vals[i]/kilo); - else - fprintf(fp, "%8llu ", vals[i]); - - if (rates[i] > mega) { - sprintf(temp, "%uM", (unsigned)(rates[i]/mega)); - fprintf(fp, "%-6s ", temp); - } else if (rates[i] > kilo) { - sprintf(temp, "%uK", (unsigned)(rates[i]/kilo)); - fprintf(fp, "%-6s ", temp); - } else - fprintf(fp, "%-6u ", (unsigned)rates[i]); -} - -void format_pair(FILE *fp, unsigned long long *vals, int i, int k) -{ - char temp[64]; - if (vals[i] > giga) - fprintf(fp, "%7lluM ", vals[i]/mega); - else if (vals[i] > mega) - fprintf(fp, "%7lluK ", vals[i]/kilo); - else - fprintf(fp, "%8llu ", vals[i]); - - if (vals[k] > giga) { - sprintf(temp, "%uM", (unsigned)(vals[k]/mega)); - fprintf(fp, "%-6s ", temp); - } else if (vals[k] > mega) { - sprintf(temp, "%uK", (unsigned)(vals[k]/kilo)); - fprintf(fp, "%-6s ", temp); - } else - fprintf(fp, "%-6u ", (unsigned)vals[k]); -} - -void print_head(FILE *fp) -{ - fprintf(fp, "#%s\n", info_source); - fprintf(fp, "%-15s ", "Interface"); - - fprintf(fp, "%8s/%-6s ", "RX Pkts", "Rate"); - fprintf(fp, "%8s/%-6s ", "TX Pkts", "Rate"); - fprintf(fp, "%8s/%-6s ", "RX Data", "Rate"); - fprintf(fp, "%8s/%-6s\n","TX Data", "Rate"); - - if (!show_errors) { - fprintf(fp, "%-15s ", ""); - fprintf(fp, "%8s/%-6s ", "RX Errs", "Drop"); - fprintf(fp, "%8s/%-6s ", "TX Errs", "Drop"); - fprintf(fp, "%8s/%-6s ", "RX Over", "Rate"); - fprintf(fp, "%8s/%-6s\n","TX Coll", "Rate"); - } else { - fprintf(fp, "%-15s ", ""); - fprintf(fp, "%8s/%-6s ", "RX Errs", "Rate"); - fprintf(fp, "%8s/%-6s ", "RX Drop", "Rate"); - fprintf(fp, "%8s/%-6s ", "RX Over", "Rate"); - fprintf(fp, "%8s/%-6s\n","RX Leng", "Rate"); - - fprintf(fp, "%-15s ", ""); - fprintf(fp, "%8s/%-6s ", "RX Crc", "Rate"); - fprintf(fp, "%8s/%-6s ", "RX Frm", "Rate"); - fprintf(fp, "%8s/%-6s ", "RX Fifo", "Rate"); - fprintf(fp, "%8s/%-6s\n","RX Miss", "Rate"); - - fprintf(fp, "%-15s ", ""); - fprintf(fp, "%8s/%-6s ", "TX Errs", "Rate"); - fprintf(fp, "%8s/%-6s ", "TX Drop", "Rate"); - fprintf(fp, "%8s/%-6s ", "TX Coll", "Rate"); - fprintf(fp, "%8s/%-6s\n","TX Carr", "Rate"); - - fprintf(fp, "%-15s ", ""); - fprintf(fp, "%8s/%-6s ", "TX Abrt", "Rate"); - fprintf(fp, "%8s/%-6s ", "TX Fifo", "Rate"); - fprintf(fp, "%8s/%-6s ", "TX Hear", "Rate"); - fprintf(fp, "%8s/%-6s\n","TX Wind", "Rate"); - } -} - -void print_one_if(FILE *fp, struct ifstat_ent *n, unsigned long long *vals) -{ - int i; - fprintf(fp, "%-15s ", n->name); - for (i=0; i<4; i++) - format_rate(fp, vals, n->rate, i); - fprintf(fp, "\n"); - - if (!show_errors) { - fprintf(fp, "%-15s ", ""); - format_pair(fp, vals, 4, 6); - format_pair(fp, vals, 5, 7); - format_rate(fp, vals, n->rate, 11); - format_rate(fp, vals, n->rate, 9); - fprintf(fp, "\n"); - } else { - fprintf(fp, "%-15s ", ""); - format_rate(fp, vals, n->rate, 4); - format_rate(fp, vals, n->rate, 6); - format_rate(fp, vals, n->rate, 11); - format_rate(fp, vals, n->rate, 10); - fprintf(fp, "\n"); - - fprintf(fp, "%-15s ", ""); - format_rate(fp, vals, n->rate, 12); - format_rate(fp, vals, n->rate, 13); - format_rate(fp, vals, n->rate, 14); - format_rate(fp, vals, n->rate, 15); - fprintf(fp, "\n"); - - fprintf(fp, "%-15s ", ""); - format_rate(fp, vals, n->rate, 5); - format_rate(fp, vals, n->rate, 7); - format_rate(fp, vals, n->rate, 9); - format_rate(fp, vals, n->rate, 17); - fprintf(fp, "\n"); - - fprintf(fp, "%-15s ", ""); - format_rate(fp, vals, n->rate, 16); - format_rate(fp, vals, n->rate, 18); - format_rate(fp, vals, n->rate, 19); - format_rate(fp, vals, n->rate, 20); - fprintf(fp, "\n"); - } -} - - -void dump_kern_db(FILE *fp) -{ - struct ifstat_ent *n, *h; - h = hist_db; - - print_head(fp); - - for (n=kern_db; n; n=n->next) { - if (!match(n->name)) - continue; - print_one_if(fp, n, n->val); - } -} - - -void dump_incr_db(FILE *fp) -{ - struct ifstat_ent *n, *h; - h = hist_db; - - print_head(fp); - - for (n=kern_db; n; n=n->next) { - int i; - unsigned long long vals[MAXS]; - struct ifstat_ent *h1; - - memcpy(vals, n->val, sizeof(vals)); - - for (h1 = h; h1; h1 = h1->next) { - if (h1->ifindex == n->ifindex) { - for (i = 0; i < MAXS; i++) - vals[i] -= h1->val[i]; - h = h1->next; - break; - } - } - if (!match(n->name)) - continue; - print_one_if(fp, n, vals); - } -} - - -static int children; - -void sigchild(int signo) -{ -} - -void update_db(int interval) -{ - struct ifstat_ent *n, *h; - - n = kern_db; - kern_db = NULL; - - load_info(); - - h = kern_db; - kern_db = n; - - for (n = kern_db; n; n = n->next) { - struct ifstat_ent *h1; - for (h1 = h; h1; h1 = h1->next) { - if (h1->ifindex == n->ifindex) { - int i; - for (i = 0; i < MAXS; i++) { - if ((long)(h1->ival[i] - n->ival[i]) < 0) { - memset(n->ival, 0, sizeof(n->ival)); - break; - } - } - for (i = 0; i < MAXS; i++) { - double sample; - unsigned long incr = h1->ival[i] - n->ival[i]; - n->val[i] += incr; - n->ival[i] = h1->ival[i]; - sample = (double)(incr*1000)/interval; - if (interval >= scan_interval) { - n->rate[i] += W*(sample-n->rate[i]); - } else if (interval >= 1000) { - if (interval >= time_constant) { - n->rate[i] = sample; - } else { - double w = W*(double)interval/scan_interval; - n->rate[i] += w*(sample-n->rate[i]); - } - } - } - - while (h != h1) { - struct ifstat_ent *tmp = h; - h = h->next; - free(tmp->name); - free(tmp); - }; - h = h1->next; - free(h1->name); - free(h1); - break; - } - } - } -} - -#define T_DIFF(a,b) (((a).tv_sec-(b).tv_sec)*1000 + ((a).tv_usec-(b).tv_usec)/1000) - - -void server_loop(int fd) -{ - struct timeval snaptime = { 0 }; - struct pollfd p; - p.fd = fd; - p.events = p.revents = POLLIN; - - sprintf(info_source, "%d.%lu sampling_interval=%d time_const=%d", - getpid(), (unsigned long)random(), scan_interval/1000, time_constant/1000); - - load_info(); - - for (;;) { - int status; - int tdiff; - struct timeval now; - - gettimeofday(&now, NULL); - tdiff = T_DIFF(now, snaptime); - if (tdiff >= scan_interval) { - update_db(tdiff); - snaptime = now; - tdiff = 0; - } - - if (poll(&p, 1, tdiff + scan_interval) > 0 - && (p.revents&POLLIN)) { - int clnt = accept(fd, NULL, NULL); - if (clnt >= 0) { - pid_t pid; - if (children >= 5) { - close(clnt); - } else if ((pid = fork()) != 0) { - if (pid>0) - children++; - close(clnt); - } else { - FILE *fp = fdopen(clnt, "w"); - if (fp) { - if (tdiff > 0) - update_db(tdiff); - dump_raw_db(fp, 0); - } - exit(0); - } - } - } - while (children && waitpid(-1, &status, WNOHANG) > 0) - children--; - } -} - -int verify_forging(int fd) -{ - struct ucred cred; - socklen_t olen = sizeof(cred); - - if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, (void*)&cred, &olen) || - olen < sizeof(cred)) - return -1; - if (cred.uid == getuid() || cred.uid == 0) - return 0; - return -1; -} - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, -"Usage: ifstat [OPTION] [ PATTERN [ PATTERN ] ]\n" -" -h, --help this message\n" -" -a, --ignore ignore history\n" -" -d, --scan=SECS sample every statistics every SECS\n" -" -e, --errors show errors\n" -" -n, --nooutput do history only\n" -" -r, --reset reset history\n" -" -s, --noupdate don;t update history\n" -" -t, --interval=SECS report average over the last SECS\n" -" -V, --version output version information\n" -" -z, --zeros show entries with zero activity\n" -" -e, --errors show errors\n" -" -z, --zeros show entries with zero activity\n"); - - exit(-1); -} - -static const struct option longopts[] = { - { "help", 0, 0, 'h' }, - { "ignore", 0, 0, 'a' }, - { "scan", 1, 0, 'd'}, - { "errors", 0, 0, 'e' }, - { "nooutput", 0, 0, 'n' }, - { "reset", 0, 0, 'r' }, - { "noupdate", 0, 0, 's' }, - { "interval", 1, 0, 't' }, - { "version", 0, 0, 'V' }, - { "zeros", 0, 0, 'z' }, - { "errors", 0, 0, 'e' }, - { "zeros", 0, 0, 'z' }, - { 0 } -}; - -int main(int argc, char *argv[]) -{ - char hist_name[128]; - struct sockaddr_un sun; - FILE *hist_fp = NULL; - int ch; - int fd; - - while ((ch = getopt_long(argc, argv, "hvVzrnasd:t:eK", - longopts, NULL)) != EOF) { - switch(ch) { - case 'z': - dump_zeros = 1; - break; - case 'r': - reset_history = 1; - break; - case 'a': - ignore_history = 1; - break; - case 's': - no_update = 1; - break; - case 'n': - no_output = 1; - break; - case 'e': - show_errors = 1; - break; - case 'd': - scan_interval = atoi(optarg) * 1000; - if (scan_interval <= 0) { - fprintf(stderr, "ifstat: invalid scan interval\n"); - exit(-1); - } - break; - case 't': - time_constant = atoi(optarg); - if (time_constant <= 0) { - fprintf(stderr, "ifstat: invalid time constant divisor\n"); - exit(-1); - } - break; - case 'v': - case 'V': - printf("ifstat utility, iproute2-ss%s\n", SNAPSHOT); - exit(0); - case 'h': - case '?': - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - sun.sun_family = AF_UNIX; - sun.sun_path[0] = 0; - sprintf(sun.sun_path+1, "ifstat%d", getuid()); - - if (scan_interval > 0) { - if (time_constant == 0) - time_constant = 60; - time_constant *= 1000; - W = 1 - 1/exp(log(10)*(double)scan_interval/time_constant); - if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - perror("ifstat: socket"); - exit(-1); - } - if (bind(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) < 0) { - perror("ifstat: bind"); - exit(-1); - } - if (listen(fd, 5) < 0) { - perror("ifstat: listen"); - exit(-1); - } - if (fork()) - exit(0); - chdir("/"); - close(0); close(1); close(2); setsid(); - signal(SIGPIPE, SIG_IGN); - signal(SIGCHLD, sigchild); - server_loop(fd); - exit(0); - } - - patterns = argv; - npatterns = argc; - - if (getenv("IFSTAT_HISTORY")) - snprintf(hist_name, sizeof(hist_name), getenv("IFSTAT_HISTORY")); - else - sprintf(hist_name, "%s/.ifstat.u%d", P_tmpdir, getuid()); - - if (reset_history) - unlink(hist_name); - - if (!ignore_history || !no_update) { - struct stat stb; - - fd = open(hist_name, O_RDWR|O_CREAT|O_NOFOLLOW, 0600); - if (fd < 0) { - perror("ifstat: open history file"); - exit(-1); - } - if ((hist_fp = fdopen(fd, "r+")) == NULL) { - perror("ifstat: fdopen history file"); - exit(-1); - } - if (flock(fileno(hist_fp), LOCK_EX)) { - perror("ifstat: flock history file"); - exit(-1); - } - if (fstat(fileno(hist_fp), &stb) != 0) { - perror("ifstat: fstat history file"); - exit(-1); - } - if (stb.st_nlink != 1 || stb.st_uid != getuid()) { - fprintf(stderr, "ifstat: something is so wrong with history file, that I prefer not to proceed.\n"); - exit(-1); - } - if (!ignore_history) { - FILE *tfp; - long uptime; - if ((tfp = fopen("/proc/uptime", "r")) != NULL) { - if (fscanf(tfp, "%ld", &uptime) != 1) - uptime = -1; - fclose(tfp); - } - if (uptime >= 0 && time(NULL) >= stb.st_mtime+uptime) { - fprintf(stderr, "ifstat: history is aged out, resetting\n"); - ftruncate(fileno(hist_fp), 0); - } - } - - load_raw_table(hist_fp); - - hist_db = kern_db; - kern_db = NULL; - } - - if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 && - (connect(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) == 0 - || (strcpy(sun.sun_path+1, "ifstat0"), - connect(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) == 0)) - && verify_forging(fd) == 0) { - FILE *sfp = fdopen(fd, "r"); - load_raw_table(sfp); - if (hist_db && source_mismatch) { - fprintf(stderr, "ifstat: history is stale, ignoring it.\n"); - hist_db = NULL; - } - fclose(sfp); - } else { - if (fd >= 0) - close(fd); - if (hist_db && info_source[0] && strcmp(info_source, "kernel")) { - fprintf(stderr, "ifstat: history is stale, ignoring it.\n"); - hist_db = NULL; - info_source[0] = 0; - } - load_info(); - if (info_source[0] == 0) - strcpy(info_source, "kernel"); - } - - if (!no_output) { - if (ignore_history || hist_db == NULL) - dump_kern_db(stdout); - else - dump_incr_db(stdout); - } - if (!no_update) { - ftruncate(fileno(hist_fp), 0); - rewind(hist_fp); - dump_raw_db(hist_fp, 1); - fflush(hist_fp); - } - exit(0); -} diff --git a/misc/lnstat.c b/misc/lnstat.c deleted file mode 100644 index 460540e..0000000 --- a/misc/lnstat.c +++ /dev/null @@ -1,337 +0,0 @@ -/* lnstat - Unified linux network statistics - * - * Copyright (C) 2004 by Harald Welte <laforge@gnumonks.org> - * - * Development of this code was funded by Astaro AG, http://www.astaro.com/ - * - * Based on original concept and ideas from predecessor rtstat.c: - * - * Copyright 2001 by Robert Olsson <robert.olsson@its.uu.se> - * Uppsala University, Sweden - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -/* Maximum number of fields that can be displayed */ -#define MAX_FIELDS 64 - -/* Maximum number of header lines */ -#define HDR_LINES 10 - -/* default field width if none specified */ -#define FIELD_WIDTH_DEFAULT 8 -#define FIELD_WIDTH_MAX 20 - -#define DEFAULT_INTERVAL 2 - -#define HDR_LINE_LENGTH (MAX_FIELDS*FIELD_WIDTH_MAX) - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> - -#include "lnstat.h" - -static struct option opts[] = { - { "version", 0, NULL, 'V' }, - { "count", 1, NULL, 'c' }, - { "dump", 1, NULL, 'd' }, - { "file", 1, NULL, 'f' }, - { "help", 0, NULL, 'h' }, - { "interval", 1, NULL, 'i' }, - { "key", 1, NULL, 'k' }, - { "subject", 1, NULL, 's' }, - { "width", 1, NULL, 'w' }, -}; - -static int usage(char *name, int exit_code) -{ - fprintf(stderr, "%s Version %s\n", name, LNSTAT_VERSION); - fprintf(stderr, "Copyright (C) 2004 by Harald Welte " - "<laforge@gnumonks.org>\n"); - fprintf(stderr, "This program is free software licensed under GNU GPLv2" - "\nwith ABSOLUTELY NO WARRANTY.\n\n"); - fprintf(stderr, "Parameters:\n"); - fprintf(stderr, "\t-V --version\t\tPrint Version of Program\n"); - fprintf(stderr, "\t-c --count <count>\t" - "Print <count> number of intervals\n"); - fprintf(stderr, "\t-d --dumpt\t\t" - "Dump list of available files/keys\n"); - fprintf(stderr, "\t-f --file <file>\tStatistics file to use\n"); - fprintf(stderr, "\t-h --help\t\tThis help message\n"); - fprintf(stderr, "\t-i --interval <intv>\t" - "Set interval to 'intv' seconds\n"); - fprintf(stderr, "\t-k --keys k,k,k,...\tDisplay only keys specified\n"); - fprintf(stderr, "\t-s --subject [0-2]\t?\n"); - fprintf(stderr, "\t-w --width n,n,n,...\tWidth for each field\n"); - fprintf(stderr, "\n"); - - exit(exit_code); -} - -struct field_param { - const char *name; - struct lnstat_field *lf; - struct { - unsigned int width; - } print; -}; - -struct field_params { - unsigned int num; - struct field_param params[MAX_FIELDS]; -}; - -static void print_line(FILE *of, const struct lnstat_file *lnstat_files, - const struct field_params *fp) -{ - int i; - - for (i = 0; i < fp->num; i++) { - struct lnstat_field *lf = fp->params[i].lf; - char formatbuf[255]; - - snprintf(formatbuf, sizeof(formatbuf)-1, "%%%ulu|", - fp->params[i].print.width); - fprintf(of, formatbuf, lf->result); - } - fputc('\n', of); -} - -/* find lnstat_field according to user specification */ -static int map_field_params(struct lnstat_file *lnstat_files, - struct field_params *fps, int interval) -{ - int i, j = 0; - struct lnstat_file *lf; - - /* no field specification on commandline, need to build default */ - if (!fps->num) { - for (lf = lnstat_files; lf; lf = lf->next) { - for (i = 0; i < lf->num_fields; i++) { - fps->params[j].lf = &lf->fields[i]; - fps->params[j].lf->file->interval.tv_sec = - interval; - if (!fps->params[j].print.width) - fps->params[j].print.width = - FIELD_WIDTH_DEFAULT; - j++; - } - } - fps->num = j; - return 1; - } - - for (i = 0; i < fps->num; i++) { - fps->params[i].lf = lnstat_find_field(lnstat_files, - fps->params[i].name); - if (!fps->params[i].lf) { - fprintf(stderr, "Field `%s' unknown\n", - fps->params[i].name); - return 0; - } - fps->params[i].lf->file->interval.tv_sec = interval; - if (!fps->params[i].print.width) - fps->params[i].print.width = FIELD_WIDTH_DEFAULT; - } - return 1; -} - -struct table_hdr { - int num_lines; - char *hdr[HDR_LINES]; -}; - -static struct table_hdr *build_hdr_string(struct lnstat_file *lnstat_files, - struct field_params *fps, - int linewidth) -{ - int h,i; - static struct table_hdr th; - int ofs = 0; - - for (i = 0; i < HDR_LINES; i++) { - th.hdr[i] = malloc(HDR_LINE_LENGTH); - memset(th.hdr[i], 0, sizeof(th.hdr[i])); - } - - for (i = 0; i < fps->num; i++) { - char *cname, *fname = fps->params[i].lf->name; - char fmt[12]; - unsigned int width = fps->params[i].print.width; - - snprintf(fmt, sizeof(fmt)-1, "%%%u.%us|", width, width); - - snprintf(th.hdr[0]+ofs, width+2, fmt, - fps->params[i].lf->file->basename); - - cname = fname; - for (h = 1; h < HDR_LINES; h++) { - if (cname - fname >= strlen(fname)) - snprintf(th.hdr[h]+ofs, width+2, fmt, ""); - else { - th.num_lines = h+1; - snprintf(th.hdr[h]+ofs, width+2, fmt, cname); - } - cname += width; - } - ofs += width+1; - } - /* fill in spaces */ - for (h = 1; h <= th.num_lines; h++) { - for (i = 0; i < ofs; i++) { - if (th.hdr[h][i] == '\0') - th.hdr[h][i] = ' '; - } - } - - return &th; -} - -static int print_hdr(FILE *of, struct table_hdr *th) -{ - int i; - - for (i = 0; i < th->num_lines; i++) { - fputs(th->hdr[i], of); - fputc('\n', of); - } - return 0; -} - - -int main(int argc, char **argv) -{ - struct lnstat_file *lnstat_files; - const char *basename; - int c; - int interval = DEFAULT_INTERVAL; - int hdr = 2; - enum { - MODE_DUMP, - MODE_NORMAL, - } mode = MODE_NORMAL; - - unsigned long count = 1; - static struct field_params fp; - int num_req_files = 0; - char *req_files[LNSTAT_MAX_FILES]; - - /* backwards compatibility mode for old tools */ - basename = strrchr(argv[0], '/'); - if (basename) - basename += 1; /* name after slash */ - else - basename = argv[0]; /* no slash */ - - if (!strcmp(basename, "rtstat")) { - /* rtstat compatibility mode */ - req_files[0] = "rt_cache"; - num_req_files = 1; - } else if (!strcmp(basename, "ctstat")) { - /* ctstat compatibility mode */ - req_files[0] = "ip_conntrack"; - num_req_files = 1; - } - - while ((c = getopt_long(argc, argv,"Vc:df:h?i:k:s:w:", - opts, NULL)) != -1) { - int i, len = 0; - char *tmp, *tok; - - switch (c) { - case 'c': - count = strtoul(optarg, NULL, 0); - break; - case 'd': - mode = MODE_DUMP; - break; - case 'f': - req_files[num_req_files++] = strdup(optarg); - break; - case '?': - case 'h': - usage(argv[0], 0); - break; - case 'i': - sscanf(optarg, "%u", &interval); - break; - case 'k': - tmp = strdup(optarg); - if (!tmp) - break; - for (tok = strtok(tmp, ","); - tok; - tok = strtok(NULL, ",")) { - if (fp.num >= MAX_FIELDS) - break; - fp.params[fp.num++].name = tok; - } - break; - case 's': - sscanf(optarg, "%u", &hdr); - break; - case 'w': - tmp = strdup(optarg); - if (!tmp) - break; - i = 0; - for (tok = strtok(tmp, ","); - tok; - tok = strtok(NULL, ",")) { - len = strtoul(tok, NULL, 0); - if (len > FIELD_WIDTH_MAX) - len = FIELD_WIDTH_MAX; - fp.params[i].print.width = len; - i++; - } - if (i == 1) { - for (i = 0; i < MAX_FIELDS; i++) - fp.params[i].print.width = len; - } - break; - default: - usage(argv[0], 1); - break; - } - } - - lnstat_files = lnstat_scan_dir(PROC_NET_STAT, num_req_files, - (const char **) req_files); - - switch (mode) { - int i; - struct table_hdr *header; - case MODE_DUMP: - lnstat_dump(stderr, lnstat_files); - break; - case MODE_NORMAL: - - if (!map_field_params(lnstat_files, &fp, interval)) - exit(1); - - header = build_hdr_string(lnstat_files, &fp, 80); - if (!header) - exit(1); - - if (interval < 1 ) - interval=1; - - for (i = 0; i < count; i++) { - if ((hdr > 1 && (! (i % 20))) || (hdr == 1 && i == 0)) - print_hdr(stdout, header); - lnstat_update(lnstat_files); - print_line(stdout, lnstat_files, &fp); - sleep(interval); - } - } - - return 1; -} - diff --git a/misc/lnstat.h b/misc/lnstat.h deleted file mode 100644 index 06774ab..0000000 --- a/misc/lnstat.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _LNSTAT_H -#define _LNSTAT_H - -#include <limits.h> - -#define LNSTAT_VERSION "0.02 041002" - -#define PROC_NET_STAT "/proc/net/stat" - -#define LNSTAT_MAX_FILES 32 -#define LNSTAT_MAX_FIELDS_PER_LINE 32 -#define LNSTAT_MAX_FIELD_NAME_LEN 32 - -struct lnstat_file; - -struct lnstat_field { - struct lnstat_file *file; - unsigned int num; /* field number in line */ - char name[LNSTAT_MAX_FIELD_NAME_LEN+1]; - unsigned long values[2]; /* two buffers for values */ - unsigned long result; -}; - -struct lnstat_file { - struct lnstat_file *next; - char path[PATH_MAX+1]; - char basename[NAME_MAX+1]; - struct timeval last_read; /* last time of read */ - struct timeval interval; /* interval */ - int compat; /* 1 == backwards compat mode */ - FILE *fp; - unsigned int num_fields; /* number of fields */ - struct lnstat_field fields[LNSTAT_MAX_FIELDS_PER_LINE]; -}; - - -struct lnstat_file *lnstat_scan_dir(const char *path, const int num_req_files, - const char **req_files); -int lnstat_update(struct lnstat_file *lnstat_files); -int lnstat_dump(FILE *outfd, struct lnstat_file *lnstat_files); -struct lnstat_field *lnstat_find_field(struct lnstat_file *lnstat_files, - const char *name); -#endif /* _LNSTAT_H */ diff --git a/misc/lnstat_util.c b/misc/lnstat_util.c deleted file mode 100644 index 59c5e96..0000000 --- a/misc/lnstat_util.c +++ /dev/null @@ -1,329 +0,0 @@ -/* lnstat.c: Unified linux network statistics - * - * Copyright (C) 2004 by Harald Welte <laforge@gnumonks.org> - * - * Development of this code was funded by Astaro AG, http://www.astaro.com/ - * - * Based on original concept and ideas from predecessor rtstat.c: - * - * Copyright 2001 by Robert Olsson <robert.olsson@its.uu.se> - * Uppsala University, Sweden - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <limits.h> -#include <time.h> - -#include <sys/time.h> -#include <sys/types.h> - -#include "lnstat.h" - -/* size of temp buffer used to read lines from procfiles */ -#define FGETS_BUF_SIZE 1024 - - -#define RTSTAT_COMPAT_LINE "entries in_hit in_slow_tot in_no_route in_brd in_martian_dst in_martian_src out_hit out_slow_tot out_slow_mc gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n" - -/* Read (and summarize for SMP) the different stats vars. */ -static int scan_lines(struct lnstat_file *lf, int i) -{ - int j, num_lines = 0; - - for (j = 0; j < lf->num_fields; j++) - lf->fields[j].values[i] = 0; - - while(!feof(lf->fp)) { - char buf[FGETS_BUF_SIZE]; - char *ptr = buf; - - num_lines++; - - fgets(buf, sizeof(buf)-1, lf->fp); - gettimeofday(&lf->last_read, NULL); - - for (j = 0; j < lf->num_fields; j++) { - unsigned long f = strtoul(ptr, &ptr, 16); - if (j == 0) - lf->fields[j].values[i] = f; - else - lf->fields[j].values[i] += f; - } - } - return num_lines; -} - -static int time_after(struct timeval *last, - struct timeval *tout, - struct timeval *now) -{ - if (now->tv_sec > last->tv_sec + tout->tv_sec) - return 1; - - if (now->tv_sec == last->tv_sec + tout->tv_sec) { - if (now->tv_usec > last->tv_usec + tout->tv_usec) - return 1; - } - - return 0; -} - -int lnstat_update(struct lnstat_file *lnstat_files) -{ - struct lnstat_file *lf; - char buf[FGETS_BUF_SIZE]; - struct timeval tv; - - gettimeofday(&tv, NULL); - - for (lf = lnstat_files; lf; lf = lf->next) { - if (time_after(&lf->last_read, &lf->interval, &tv)) { - int i; - struct lnstat_field *lfi; - - rewind(lf->fp); - if (!lf->compat) { - /* skip first line */ - fgets(buf, sizeof(buf)-1, lf->fp); - } - scan_lines(lf, 1); - - for (i = 0, lfi = &lf->fields[i]; - i < lf->num_fields; i++, lfi = &lf->fields[i]) { - if (i == 0) - lfi->result = lfi->values[1]; - else - lfi->result = (lfi->values[1]-lfi->values[0]) - / lf->interval.tv_sec; - } - - rewind(lf->fp); - fgets(buf, sizeof(buf)-1, lf->fp); - scan_lines(lf, 0); - } - } - - return 0; -} - -/* scan first template line and fill in per-field data structures */ -static int __lnstat_scan_fields(struct lnstat_file *lf, char *buf) -{ - char *tok; - int i; - - tok = strtok(buf, " \t\n"); - for (i = 0; i < LNSTAT_MAX_FIELDS_PER_LINE; i++) { - lf->fields[i].file = lf; - strncpy(lf->fields[i].name, tok, LNSTAT_MAX_FIELD_NAME_LEN); - /* has to be null-terminate since we initialize to zero - * and field size is NAME_LEN + 1 */ - tok = strtok(NULL, " \t\n"); - if (!tok) { - lf->num_fields = i+1; - return 0; - } - } - return 0; -} - -static int lnstat_scan_fields(struct lnstat_file *lf) -{ - char buf[FGETS_BUF_SIZE]; - - rewind(lf->fp); - fgets(buf, sizeof(buf)-1, lf->fp); - - return __lnstat_scan_fields(lf, buf); -} - -/* fake function emulating lnstat_scan_fields() for old kernels */ -static int lnstat_scan_compat_rtstat_fields(struct lnstat_file *lf) -{ - char buf[FGETS_BUF_SIZE]; - - strncpy(buf, RTSTAT_COMPAT_LINE, sizeof(buf)-1); - - return __lnstat_scan_fields(lf, buf); -} - -/* find out whether string 'name; is in given string array */ -static int name_in_array(const int num, const char **arr, const char *name) -{ - int i; - for (i = 0; i < num; i++) { - if (!strcmp(arr[i], name)) - return 1; - } - return 0; -} - -/* allocate lnstat_file and open given file */ -static struct lnstat_file *alloc_and_open(const char *path, const char *file) -{ - struct lnstat_file *lf; - - /* allocate */ - lf = malloc(sizeof(*lf)); - if (!lf) - return NULL; - - /* initialize */ - memset(lf, 0, sizeof(*lf)); - - /* de->d_name is guaranteed to be <= NAME_MAX */ - strcpy(lf->basename, file); - strcpy(lf->path, path); - strcat(lf->path, "/"); - strcat(lf->path, lf->basename); - - /* initialize to default */ - lf->interval.tv_sec = 1; - - /* open */ - lf->fp = fopen(lf->path, "r"); - if (!lf->fp) { - free(lf); - return NULL; - } - - return lf; -} - - -/* lnstat_scan_dir - find and parse all available statistics files/fields */ -struct lnstat_file *lnstat_scan_dir(const char *path, const int num_req_files, - const char **req_files) -{ - DIR *dir; - struct lnstat_file *lnstat_files = NULL; - struct dirent *de; - - if (!path) - path = PROC_NET_STAT; - - dir = opendir(path); - if (!dir) { - struct lnstat_file *lf; - /* Old kernel, before /proc/net/stat was introduced */ - fprintf(stderr, "Your kernel doesn't have lnstat support. "); - - /* we only support rtstat, not multiple files */ - if (num_req_files >= 2) { - fputc('\n', stderr); - return NULL; - } - - /* we really only accept rt_cache */ - if (num_req_files && !name_in_array(num_req_files, - req_files, "rt_cache")) { - fputc('\n', stderr); - return NULL; - } - - fprintf(stderr, "Fallback to old rtstat-only operation\n"); - - lf = alloc_and_open("/proc/net", "rt_cache_stat"); - if (!lf) - return NULL; - lf->compat = 1; - strncpy(lf->basename, "rt_cache", sizeof(lf->basename)); - - /* FIXME: support for old files */ - if (lnstat_scan_compat_rtstat_fields(lf) < 0) - return NULL; - - lf->next = lnstat_files; - lnstat_files = lf; - return lnstat_files; - } - - while ((de = readdir(dir))) { - struct lnstat_file *lf; - - if (de->d_type != DT_REG) - continue; - - if (num_req_files && !name_in_array(num_req_files, - req_files, de->d_name)) - continue; - - lf = alloc_and_open(path, de->d_name); - if (!lf) - return NULL; - - /* fill in field structure */ - if (lnstat_scan_fields(lf) < 0) - return NULL; - - /* prepend to global list */ - lf->next = lnstat_files; - lnstat_files = lf; - } - closedir(dir); - - return lnstat_files; -} - -int lnstat_dump(FILE *outfd, struct lnstat_file *lnstat_files) -{ - struct lnstat_file *lf; - - for (lf = lnstat_files; lf; lf = lf->next) { - int i; - - fprintf(outfd, "%s:\n", lf->path); - - for (i = 0; i < lf->num_fields; i++) - fprintf(outfd, "\t%2u: %s\n", i+1, lf->fields[i].name); - - } - return 0; -} - -struct lnstat_field *lnstat_find_field(struct lnstat_file *lnstat_files, - const char *name) -{ - struct lnstat_file *lf; - struct lnstat_field *ret = NULL; - const char *colon = strchr(name, ':'); - char *file; - const char *field; - - if (colon) { - file = strndup(name, colon-name); - field = colon+1; - } else { - file = NULL; - field = name; - } - - for (lf = lnstat_files; lf; lf = lf->next) { - int i; - - if (file && strcmp(file, lf->basename)) - continue; - - for (i = 0; i < lf->num_fields; i++) { - if (!strcmp(field, lf->fields[i].name)) { - ret = &lf->fields[i]; - goto out; - } - } - } -out: - if (file) - free(file); - - return ret; -} diff --git a/misc/netbug b/misc/netbug deleted file mode 100755 index 6d13c8e..0000000 --- a/misc/netbug +++ /dev/null @@ -1,53 +0,0 @@ -#! /bin/bash - -echo -n "Send network configuration summary to [ENTER means kuznet@ms2.inr.ac.ru] " -IFS="" read mail || exit 1 -[ -z "$mail" ] && mail=kuznet@ms2.inr.ac.ru - - -netbug="" -while [ "$netbug" = "" ]; do - netbug=`echo netbug.$$.$RANDOM` - if [ -e /tmp/$netbug ]; then - netbug="" - fi -done - -tmppath=/tmp/$netbug - -trap "rm -rf $tmppath $tmppath.tar.gz" 0 SIGINT - -mkdir $tmppath -mkdir $tmppath/net - -cat /proc/slabinfo > $tmppath/slabinfo -cat /proc/net/netstat > $tmppath/net/netstat -cat /proc/net/unix > $tmppath/net/unix -cat /proc/net/packet > $tmppath/net/packet -cat /proc/net/netlink > $tmppath/net/netlink -cat /proc/net/psched > $tmppath/net/psched -cat /proc/net/softnet_stat > $tmppath/net/softnet_stat -cat /proc/net/sockstat > $tmppath/net/sockstat -cat /proc/net/tcp > $tmppath/net/tcp -cat /proc/net/udp > $tmppath/net/udp -cat /proc/net/raw > $tmppath/net/raw -cat /proc/net/snmp > $tmppath/net/snmp - -ss -aioem -D $tmppath/tcpdiag - -if [ -e /proc/net/tcp6 ]; then - cat /proc/net/sockstat6 > $tmppath/net/sockstat6 - cat /proc/net/tcp6 > $tmppath/net/tcp6 - cat /proc/net/udp6 > $tmppath/net/udp6 - cat /proc/net/raw6 > $tmppath/net/raw6 - cat /proc/net/snmp6 > $tmppath/net/snmp6 -fi - -cd /tmp -tar c $netbug | gzip -9c > $netbug.tar.gz - -uuencode $netbug.tar.gz $netbug.tar.gz | mail -s $netbug "$mail" - -echo "Sending to <$mail>; subject is $netbug" - -exit 0 diff --git a/misc/nstat.c b/misc/nstat.c deleted file mode 100644 index fc4b03b..0000000 --- a/misc/nstat.c +++ /dev/null @@ -1,621 +0,0 @@ -/* - * nstat.c handy utility to read counters /proc/net/netstat and snmp - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <sys/time.h> -#include <fnmatch.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/poll.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <signal.h> -#include <math.h> - -#include <SNAPSHOT.h> - -int dump_zeros = 0; -int reset_history = 0; -int ignore_history = 0; -int no_output = 0; -int no_update = 0; -int scan_interval = 0; -int time_constant = 0; -double W; -char **patterns; -int npatterns; - -char info_source[128]; -int source_mismatch; - -int generic_proc_open(char *env, char *name) -{ - char store[128]; - char *p = getenv(env); - if (!p) { - p = getenv("PROC_ROOT") ? : "/proc"; - snprintf(store, sizeof(store)-1, "%s/%s", p, name); - p = store; - } - return open(store, O_RDONLY); -} - -int net_netstat_open(void) -{ - return generic_proc_open("PROC_NET_NETSTAT", "net/netstat"); -} - -int net_snmp_open(void) -{ - return generic_proc_open("PROC_NET_SNMP", "net/snmp"); -} - -int net_snmp6_open(void) -{ - return generic_proc_open("PROC_NET_SNMP6", "net/snmp6"); -} - -struct nstat_ent -{ - struct nstat_ent *next; - char *id; - unsigned long long val; - unsigned long ival; - double rate; -}; - -struct nstat_ent *kern_db; -struct nstat_ent *hist_db; - -char *useless_numbers[] = { -"IpForwarding", "IpDefaultTTL", -"TcpRtoAlgorithm", "TcpRtoMin", "TcpRtoMax", -"TcpMaxConn", "TcpCurrEstab" -}; - -int useless_number(char *id) -{ - int i; - for (i=0; i<sizeof(useless_numbers)/sizeof(*useless_numbers); i++) - if (strcmp(id, useless_numbers[i]) == 0) - return 1; - return 0; -} - -int match(char *id) -{ - int i; - - if (npatterns == 0) - return 1; - - for (i=0; i<npatterns; i++) { - if (!fnmatch(patterns[i], id, 0)) - return 1; - } - return 0; -} - -void load_good_table(FILE *fp) -{ - char buf[4096]; - struct nstat_ent *db = NULL; - struct nstat_ent *n; - - while (fgets(buf, sizeof(buf), fp) != NULL) { - int nr; - unsigned long long val; - double rate; - char idbuf[sizeof(buf)]; - if (buf[0] == '#') { - buf[strlen(buf)-1] = 0; - if (info_source[0] && strcmp(info_source, buf+1)) - source_mismatch = 1; - info_source[0] = 0; - strncat(info_source, buf+1, sizeof(info_source)-1); - continue; - } - /* idbuf is as big as buf, so this is safe */ - nr = sscanf(buf, "%s%llu%lg", idbuf, &val, &rate); - if (nr < 2) - abort(); - if (nr < 3) - rate = 0; - if (useless_number(idbuf)) - continue; - if ((n = malloc(sizeof(*n))) == NULL) - abort(); - n->id = strdup(idbuf); - n->ival = (unsigned long)val; - n->val = val; - n->rate = rate; - n->next = db; - db = n; - } - - while (db) { - n = db; - db = db->next; - n->next = kern_db; - kern_db = n; - } -} - - -void load_ugly_table(FILE *fp) -{ - char buf[4096]; - struct nstat_ent *db = NULL; - struct nstat_ent *n; - - while (fgets(buf, sizeof(buf), fp) != NULL) { - char idbuf[sizeof(buf)]; - int off; - char *p; - - p = strchr(buf, ':'); - if (!p) - abort(); - *p = 0; - idbuf[0] = 0; - strncat(idbuf, buf, sizeof(idbuf) - 1); - off = p - buf; - p += 2; - - while (*p) { - char *next; - if ((next = strchr(p, ' ')) != NULL) - *next++ = 0; - else if ((next = strchr(p, '\n')) != NULL) - *next++ = 0; - if (off < sizeof(idbuf)) { - idbuf[off] = 0; - strncat(idbuf, p, sizeof(idbuf) - off - 1); - } - n = malloc(sizeof(*n)); - if (!n) - abort(); - n->id = strdup(idbuf); - n->rate = 0; - n->next = db; - db = n; - p = next; - } - n = db; - if (fgets(buf, sizeof(buf), fp) == NULL) - abort(); - do { - p = strrchr(buf, ' '); - if (!p) - abort(); - *p = 0; - if (sscanf(p+1, "%lu", &n->ival) != 1) - abort(); - n->val = n->ival; - /* Trick to skip "dummy" trailing ICMP MIB in 2.4 */ - if (strcmp(idbuf, "IcmpOutAddrMaskReps") == 0) - idbuf[5] = 0; - else - n = n->next; - } while (p > buf + off + 2); - } - - while (db) { - n = db; - db = db->next; - if (useless_number(n->id)) { - free(n->id); - free(n); - } else { - n->next = kern_db; - kern_db = n; - } - } -} - -void load_snmp(void) -{ - FILE *fp = fdopen(net_snmp_open(), "r"); - if (fp) { - load_ugly_table(fp); - fclose(fp); - } -} - -void load_snmp6(void) -{ - FILE *fp = fdopen(net_snmp6_open(), "r"); - if (fp) { - load_good_table(fp); - fclose(fp); - } -} - -void load_netstat(void) -{ - FILE *fp = fdopen(net_netstat_open(), "r"); - if (fp) { - load_ugly_table(fp); - fclose(fp); - } -} - -void dump_kern_db(FILE *fp, int to_hist) -{ - struct nstat_ent *n, *h; - h = hist_db; - fprintf(fp, "#%s\n", info_source); - for (n=kern_db; n; n=n->next) { - unsigned long long val = n->val; - if (!dump_zeros && !val && !n->rate) - continue; - if (!match(n->id)) { - struct nstat_ent *h1; - if (!to_hist) - continue; - for (h1 = h; h1; h1 = h1->next) { - if (strcmp(h1->id, n->id) == 0) { - val = h1->val; - h = h1->next; - break; - } - } - } - fprintf(fp, "%-32s%-16llu%6.1f\n", n->id, val, n->rate); - } -} - -void dump_incr_db(FILE *fp) -{ - struct nstat_ent *n, *h; - h = hist_db; - fprintf(fp, "#%s\n", info_source); - for (n=kern_db; n; n=n->next) { - int ovfl = 0; - unsigned long long val = n->val; - struct nstat_ent *h1; - for (h1 = h; h1; h1 = h1->next) { - if (strcmp(h1->id, n->id) == 0) { - if (val < h1->val) { - ovfl = 1; - val = h1->val; - } - val -= h1->val; - h = h1->next; - break; - } - } - if (!dump_zeros && !val && !n->rate) - continue; - if (!match(n->id)) - continue; - fprintf(fp, "%-32s%-16llu%6.1f%s\n", n->id, val, - n->rate, ovfl?" (overflow)":""); - } -} - -static int children; - -void sigchild(int signo) -{ -} - -void update_db(int interval) -{ - struct nstat_ent *n, *h; - - n = kern_db; - kern_db = NULL; - - load_netstat(); - load_snmp6(); - load_snmp(); - - h = kern_db; - kern_db = n; - - for (n = kern_db; n; n = n->next) { - struct nstat_ent *h1; - for (h1 = h; h1; h1 = h1->next) { - if (strcmp(h1->id, n->id) == 0) { - double sample; - unsigned long incr = h1->ival - n->ival; - n->val += incr; - n->ival = h1->ival; - sample = (double)(incr*1000)/interval; - if (interval >= scan_interval) { - n->rate += W*(sample-n->rate); - } else if (interval >= 1000) { - if (interval >= time_constant) { - n->rate = sample; - } else { - double w = W*(double)interval/scan_interval; - n->rate += w*(sample-n->rate); - } - } - - while (h != h1) { - struct nstat_ent *tmp = h; - h = h->next; - free(tmp->id); - free(tmp); - }; - h = h1->next; - free(h1->id); - free(h1); - break; - } - } - } -} - -#define T_DIFF(a,b) (((a).tv_sec-(b).tv_sec)*1000 + ((a).tv_usec-(b).tv_usec)/1000) - - -void server_loop(int fd) -{ - struct timeval snaptime = { 0 }; - struct pollfd p; - p.fd = fd; - p.events = p.revents = POLLIN; - - sprintf(info_source, "%d.%lu sampling_interval=%d time_const=%d", - getpid(), (unsigned long)random(), scan_interval/1000, time_constant/1000); - - load_netstat(); - load_snmp6(); - load_snmp(); - - for (;;) { - int status; - int tdiff; - struct timeval now; - gettimeofday(&now, NULL); - tdiff = T_DIFF(now, snaptime); - if (tdiff >= scan_interval) { - update_db(tdiff); - snaptime = now; - tdiff = 0; - } - if (poll(&p, 1, tdiff + scan_interval) > 0 - && (p.revents&POLLIN)) { - int clnt = accept(fd, NULL, NULL); - if (clnt >= 0) { - pid_t pid; - if (children >= 5) { - close(clnt); - } else if ((pid = fork()) != 0) { - if (pid>0) - children++; - close(clnt); - } else { - FILE *fp = fdopen(clnt, "w"); - if (fp) { - if (tdiff > 0) - update_db(tdiff); - dump_kern_db(fp, 0); - } - exit(0); - } - } - } - while (children && waitpid(-1, &status, WNOHANG) > 0) - children--; - } -} - -int verify_forging(int fd) -{ - struct ucred cred; - socklen_t olen = sizeof(cred); - - if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, (void*)&cred, &olen) || - olen < sizeof(cred)) - return -1; - if (cred.uid == getuid() || cred.uid == 0) - return 0; - return -1; -} - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, -"Usage: nstat [ -h?vVzrnasd:t: ] [ PATTERN [ PATTERN ] ]\n" - ); - exit(-1); -} - - -int main(int argc, char *argv[]) -{ - char hist_name[128]; - struct sockaddr_un sun; - FILE *hist_fp = NULL; - int ch; - int fd; - - while ((ch = getopt(argc, argv, "h?vVzrnasd:t:")) != EOF) { - switch(ch) { - case 'z': - dump_zeros = 1; - break; - case 'r': - reset_history = 1; - break; - case 'a': - ignore_history = 1; - break; - case 's': - no_update = 1; - break; - case 'n': - no_output = 1; - break; - case 'd': - scan_interval = 1000*atoi(optarg); - break; - case 't': - if (sscanf(optarg, "%d", &time_constant) != 1 || - time_constant <= 0) { - fprintf(stderr, "nstat: invalid time constant divisor\n"); - exit(-1); - } - break; - case 'v': - case 'V': - printf("nstat utility, iproute2-ss%s\n", SNAPSHOT); - exit(0); - case 'h': - case '?': - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - sun.sun_family = AF_UNIX; - sun.sun_path[0] = 0; - sprintf(sun.sun_path+1, "nstat%d", getuid()); - - if (scan_interval > 0) { - if (time_constant == 0) - time_constant = 60; - time_constant *= 1000; - W = 1 - 1/exp(log(10)*(double)scan_interval/time_constant); - if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - perror("nstat: socket"); - exit(-1); - } - if (bind(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) < 0) { - perror("nstat: bind"); - exit(-1); - } - if (listen(fd, 5) < 0) { - perror("nstat: listen"); - exit(-1); - } - if (fork()) - exit(0); - chdir("/"); - close(0); close(1); close(2); setsid(); - signal(SIGPIPE, SIG_IGN); - signal(SIGCHLD, sigchild); - server_loop(fd); - exit(0); - } - - patterns = argv; - npatterns = argc; - - if (getenv("NSTAT_HISTORY")) - snprintf(hist_name, sizeof(hist_name), getenv("NSTAT_HISTORY")); - else - sprintf(hist_name, "/tmp/.nstat.u%d", getuid()); - - if (reset_history) - unlink(hist_name); - - if (!ignore_history || !no_update) { - struct stat stb; - - fd = open(hist_name, O_RDWR|O_CREAT|O_NOFOLLOW, 0600); - if (fd < 0) { - perror("nstat: open history file"); - exit(-1); - } - if ((hist_fp = fdopen(fd, "r+")) == NULL) { - perror("nstat: fdopen history file"); - exit(-1); - } - if (flock(fileno(hist_fp), LOCK_EX)) { - perror("nstat: flock history file"); - exit(-1); - } - if (fstat(fileno(hist_fp), &stb) != 0) { - perror("nstat: fstat history file"); - exit(-1); - } - if (stb.st_nlink != 1 || stb.st_uid != getuid()) { - fprintf(stderr, "nstat: something is so wrong with history file, that I prefer not to proceed.\n"); - exit(-1); - } - if (!ignore_history) { - FILE *tfp; - long uptime; - if ((tfp = fopen("/proc/uptime", "r")) != NULL) { - if (fscanf(tfp, "%ld", &uptime) != 1) - uptime = -1; - fclose(tfp); - } - if (uptime >= 0 && time(NULL) >= stb.st_mtime+uptime) { - fprintf(stderr, "nstat: history is aged out, resetting\n"); - ftruncate(fileno(hist_fp), 0); - } - } - - load_good_table(hist_fp); - - hist_db = kern_db; - kern_db = NULL; - } - - if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 && - (connect(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) == 0 - || (strcpy(sun.sun_path+1, "nstat0"), - connect(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) == 0)) - && verify_forging(fd) == 0) { - FILE *sfp = fdopen(fd, "r"); - load_good_table(sfp); - if (hist_db && source_mismatch) { - fprintf(stderr, "nstat: history is stale, ignoring it.\n"); - hist_db = NULL; - } - fclose(sfp); - } else { - if (fd >= 0) - close(fd); - if (hist_db && info_source[0] && strcmp(info_source, "kernel")) { - fprintf(stderr, "nstat: history is stale, ignoring it.\n"); - hist_db = NULL; - info_source[0] = 0; - } - load_netstat(); - load_snmp6(); - load_snmp(); - if (info_source[0] == 0) - strcpy(info_source, "kernel"); - } - - if (!no_output) { - if (ignore_history || hist_db == NULL) - dump_kern_db(stdout, 0); - else - dump_incr_db(stdout); - } - if (!no_update) { - ftruncate(fileno(hist_fp), 0); - rewind(hist_fp); - dump_kern_db(hist_fp, 1); - fflush(hist_fp); - } - exit(0); -} diff --git a/misc/rtacct.c b/misc/rtacct.c deleted file mode 100644 index 0d8ff7b..0000000 --- a/misc/rtacct.c +++ /dev/null @@ -1,628 +0,0 @@ -/* - * rtacct.c Applet to display contents of /proc/net/rt_acct. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <sys/time.h> -#include <fnmatch.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/poll.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <signal.h> -#include <math.h> - -#include "rt_names.h" - -#include <SNAPSHOT.h> - -int reset_history = 0; -int ignore_history = 0; -int no_output = 0; -int no_update = 0; -int scan_interval = 0; -int time_constant = 0; -int dump_zeros = 0; -unsigned long magic_number = 0; -double W; - -int generic_proc_open(char *env, char *name) -{ - char store[1024]; - char *p = getenv(env); - if (!p) { - p = getenv("PROC_ROOT") ? : "/proc"; - snprintf(store, sizeof(store)-1, "%s/%s", p, name); - p = store; - } - return open(store, O_RDONLY); -} - -int net_rtacct_open(void) -{ - return generic_proc_open("PROC_NET_RTACCT", "net/rt_acct"); -} - -__u32 rmap[256/4]; - -struct rtacct_data -{ - __u32 ival[256*4]; - - unsigned long long val[256*4]; - double rate[256*4]; - char signature[128]; -}; - -struct rtacct_data kern_db_static; - -struct rtacct_data *kern_db = &kern_db_static; -struct rtacct_data *hist_db; - -void nread(int fd, char *buf, int tot) -{ - int count = 0; - - while (count < tot) { - int n = read(fd, buf+count, tot-count); - if (n < 0) { - if (errno == EINTR) - continue; - exit(-1); - } - if (n == 0) - exit(-1); - count += n; - } -} - - -__u32 *read_kern_table(__u32 *tbl) -{ - static __u32 *tbl_ptr; - int fd; - - if (magic_number) { - if (tbl_ptr != NULL) - return tbl_ptr; - - fd = open("/dev/mem", O_RDONLY); - if (fd < 0) { - perror("magic open"); - exit(-1); - } - tbl_ptr = mmap(NULL, 4096, - PROT_READ, - MAP_SHARED, - fd, magic_number); - if ((unsigned long)tbl_ptr == ~0UL) { - perror("magic mmap"); - exit(-1); - } - close(fd); - return tbl_ptr; - } - - fd = net_rtacct_open(); - if (fd >= 0) { - nread(fd, (char*)tbl, 256*16); - close(fd); - } else { - memset(tbl, 0, 256*16); - } - return tbl; -} - -void format_rate(FILE *fp, double rate) -{ - char temp[64]; - - if (rate > 1024*1024) { - sprintf(temp, "%uM", (unsigned)rint(rate/(1024*1024))); - fprintf(fp, " %-10s", temp); - } else if (rate > 1024) { - sprintf(temp, "%uK", (unsigned)rint(rate/1024)); - fprintf(fp, " %-10s", temp); - } else - fprintf(fp, " %-10u", (unsigned)rate); -} - -void format_count(FILE *fp, unsigned long long val) -{ - if (val > 1024*1024*1024) - fprintf(fp, " %10lluM", val/(1024*1024)); - else if (val > 1024*1024) - fprintf(fp, " %10lluK", val/1024); - else - fprintf(fp, " %10llu", val); -} - -void dump_abs_db(FILE *fp) -{ - int realm; - char b1[16]; - - if (!no_output) { - fprintf(fp, "#%s\n", kern_db->signature); - fprintf(fp, -"%-10s " -"%-10s " -"%-10s " -"%-10s " -"%-10s " -"\n" - , "Realm", "BytesTo", "PktsTo", "BytesFrom", "PktsFrom"); - fprintf(fp, -"%-10s " -"%-10s " -"%-10s " -"%-10s " -"%-10s " -"\n" - , "", "BPSTo", "PPSTo", "BPSFrom", "PPSFrom"); - - } - - for (realm=0; realm<256; realm++) { - int i; - unsigned long long *val; - double *rate; - - if (!(rmap[realm>>5] & (1<<(realm&0x1f)))) - continue; - - val = &kern_db->val[realm*4]; - rate = &kern_db->rate[realm*4]; - - if (!dump_zeros && - !val[0] && !rate[0] && - !val[1] && !rate[1] && - !val[2] && !rate[2] && - !val[3] && !rate[3]) - continue; - - if (hist_db) { - memcpy(&hist_db->val[realm*4], val, sizeof(*val)*4); - } - - if (no_output) - continue; - - fprintf(fp, "%-10s", rtnl_rtrealm_n2a(realm, b1, sizeof(b1))); - for (i = 0; i < 4; i++) - format_count(fp, val[i]); - fprintf(fp, "\n%-10s", ""); - for (i = 0; i < 4; i++) - format_rate(fp, rate[i]); - fprintf(fp, "\n"); - } -} - - -void dump_incr_db(FILE *fp) -{ - int k, realm; - char b1[16]; - - if (!no_output) { - fprintf(fp, "#%s\n", kern_db->signature); - fprintf(fp, -"%-10s " -"%-10s " -"%-10s " -"%-10s " -"%-10s " -"\n" - , "Realm", "BytesTo", "PktsTo", "BytesFrom", "PktsFrom"); - fprintf(fp, -"%-10s " -"%-10s " -"%-10s " -"%-10s " -"%-10s " -"\n" - , "", "BPSTo", "PPSTo", "BPSFrom", "PPSFrom"); - } - - for (realm=0; realm<256; realm++) { - int ovfl = 0; - int i; - unsigned long long *val; - double *rate; - unsigned long long rval[4]; - - if (!(rmap[realm>>5] & (1<<(realm&0x1f)))) - continue; - - val = &kern_db->val[realm*4]; - rate = &kern_db->rate[realm*4]; - - for (k=0; k<4; k++) { - rval[k] = val[k]; - if (rval[k] < hist_db->val[realm*4+k]) - ovfl = 1; - else - rval[k] -= hist_db->val[realm*4+k]; - } - if (ovfl) { - for (k=0; k<4; k++) - rval[k] = val[k]; - } - if (hist_db) { - memcpy(&hist_db->val[realm*4], val, sizeof(*val)*4); - } - - if (no_output) - continue; - - if (!dump_zeros && - !rval[0] && !rate[0] && - !rval[1] && !rate[1] && - !rval[2] && !rate[2] && - !rval[3] && !rate[3]) - continue; - - - fprintf(fp, "%-10s", rtnl_rtrealm_n2a(realm, b1, sizeof(b1))); - for (i = 0; i < 4; i++) - format_count(fp, rval[i]); - fprintf(fp, "\n%-10s", ""); - for (i = 0; i < 4; i++) - format_rate(fp, rate[i]); - fprintf(fp, "\n"); - } -} - - -static int children; - -void sigchild(int signo) -{ -} - -/* Server side only: read kernel data, update tables, calculate rates. */ - -void update_db(int interval) -{ - int i; - __u32 *ival; - __u32 _ival[256*4]; - - ival = read_kern_table(_ival); - - for (i=0; i<256*4; i++) { - double sample; - __u32 incr = ival[i] - kern_db->ival[i]; - - if (ival[i] == 0 && incr == 0 && - kern_db->val[i] == 0 && kern_db->rate[i] == 0) - continue; - - kern_db->val[i] += incr; - kern_db->ival[i] = ival[i]; - sample = (double)(incr*1000)/interval; - if (interval >= scan_interval) { - kern_db->rate[i] += W*(sample-kern_db->rate[i]); - } else if (interval >= 1000) { - if (interval >= time_constant) { - kern_db->rate[i] = sample; - } else { - double w = W*(double)interval/scan_interval; - kern_db->rate[i] += w*(sample-kern_db->rate[i]); - } - } - } -} - -void send_db(int fd) -{ - int tot = 0; - - while (tot < sizeof(*kern_db)) { - int n = write(fd, ((char*)kern_db) + tot, sizeof(*kern_db)-tot); - if (n < 0) { - if (errno == EINTR) - continue; - return; - } - tot += n; - } -} - - - -#define T_DIFF(a,b) (((a).tv_sec-(b).tv_sec)*1000 + ((a).tv_usec-(b).tv_usec)/1000) - - -void pad_kern_table(struct rtacct_data *dat, __u32 *ival) -{ - int i; - memset(dat->rate, 0, sizeof(dat->rate)); - if (dat->ival != ival) - memcpy(dat->ival, ival, sizeof(dat->ival)); - for (i=0; i<256*4; i++) - dat->val[i] = ival[i]; -} - -void server_loop(int fd) -{ - struct timeval snaptime = { 0 }; - struct pollfd p; - p.fd = fd; - p.events = p.revents = POLLIN; - - sprintf(kern_db->signature, - "%u.%lu sampling_interval=%d time_const=%d", - (unsigned) getpid(), (unsigned long)random(), - scan_interval/1000, time_constant/1000); - - pad_kern_table(kern_db, read_kern_table(kern_db->ival)); - - for (;;) { - int status; - int tdiff; - struct timeval now; - gettimeofday(&now, NULL); - tdiff = T_DIFF(now, snaptime); - if (tdiff >= scan_interval) { - update_db(tdiff); - snaptime = now; - tdiff = 0; - } - if (poll(&p, 1, tdiff + scan_interval) > 0 - && (p.revents&POLLIN)) { - int clnt = accept(fd, NULL, NULL); - if (clnt >= 0) { - pid_t pid; - if (children >= 5) { - close(clnt); - } else if ((pid = fork()) != 0) { - if (pid>0) - children++; - close(clnt); - } else { - if (tdiff > 0) - update_db(tdiff); - send_db(clnt); - exit(0); - } - } - } - while (children && waitpid(-1, &status, WNOHANG) > 0) - children--; - } -} - -int verify_forging(int fd) -{ - struct ucred cred; - socklen_t olen = sizeof(cred); - - if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, (void*)&cred, &olen) || - olen < sizeof(cred)) - return -1; - if (cred.uid == getuid() || cred.uid == 0) - return 0; - return -1; -} - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, -"Usage: rtacct [ -h?vVzrnasd:t: ] [ ListOfRealms ]\n" - ); - exit(-1); -} - -int main(int argc, char *argv[]) -{ - char hist_name[128]; - struct sockaddr_un sun; - int ch; - int fd; - - while ((ch = getopt(argc, argv, "h?vVzrM:nasd:t:")) != EOF) { - switch(ch) { - case 'z': - dump_zeros = 1; - break; - case 'r': - reset_history = 1; - break; - case 'a': - ignore_history = 1; - break; - case 's': - no_update = 1; - break; - case 'n': - no_output = 1; - break; - case 'd': - scan_interval = 1000*atoi(optarg); - break; - case 't': - if (sscanf(optarg, "%d", &time_constant) != 1 || - time_constant <= 0) { - fprintf(stderr, "rtacct: invalid time constant divisor\n"); - exit(-1); - } - break; - case 'v': - case 'V': - printf("rtacct utility, iproute2-ss%s\n", SNAPSHOT); - exit(0); - case 'M': - /* Some secret undocumented option, nobody - * is expected to ask about its sense. See? - */ - sscanf(optarg, "%lx", &magic_number); - break; - case 'h': - case '?': - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - if (argc) { - while (argc > 0) { - __u32 realm; - if (rtnl_rtrealm_a2n(&realm, argv[0])) { - fprintf(stderr, "Warning: realm \"%s\" does not exist.\n", argv[0]); - exit(-1); - } - rmap[realm>>5] |= (1<<(realm&0x1f)); - argc--; argv++; - } - } else { - memset(rmap, ~0, sizeof(rmap)); - /* Always suppress zeros. */ - dump_zeros = 0; - } - - sun.sun_family = AF_UNIX; - sun.sun_path[0] = 0; - sprintf(sun.sun_path+1, "rtacct%d", getuid()); - - if (scan_interval > 0) { - if (time_constant == 0) - time_constant = 60; - time_constant *= 1000; - W = 1 - 1/exp(log(10)*(double)scan_interval/time_constant); - if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - perror("rtacct: socket"); - exit(-1); - } - if (bind(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) < 0) { - perror("rtacct: bind"); - exit(-1); - } - if (listen(fd, 5) < 0) { - perror("rtacct: listen"); - exit(-1); - } - if (fork()) - exit(0); - chdir("/"); - close(0); close(1); close(2); setsid(); - signal(SIGPIPE, SIG_IGN); - signal(SIGCHLD, sigchild); - server_loop(fd); - exit(0); - } - - if (getenv("RTACCT_HISTORY")) - snprintf(hist_name, sizeof(hist_name), getenv("RTACCT_HISTORY")); - else - sprintf(hist_name, "/tmp/.rtacct.u%d", getuid()); - - if (reset_history) - unlink(hist_name); - - if (!ignore_history || !no_update) { - struct stat stb; - - fd = open(hist_name, O_RDWR|O_CREAT|O_NOFOLLOW, 0600); - if (fd < 0) { - perror("rtacct: open history file"); - exit(-1); - } - if (flock(fd, LOCK_EX)) { - perror("rtacct: flock history file"); - exit(-1); - } - if (fstat(fd, &stb) != 0) { - perror("rtacct: fstat history file"); - exit(-1); - } - if (stb.st_nlink != 1 || stb.st_uid != getuid()) { - fprintf(stderr, "rtacct: something is so wrong with history file, that I prefer not to proceed.\n"); - exit(-1); - } - if (stb.st_size != sizeof(*hist_db)) - write(fd, kern_db, sizeof(*hist_db)); - - hist_db = mmap(NULL, sizeof(*hist_db), - PROT_READ|PROT_WRITE, - no_update ? MAP_PRIVATE : MAP_SHARED, - fd, 0); - - if ((unsigned long)hist_db == ~0UL) { - perror("mmap"); - exit(-1); - } - - if (!ignore_history) { - FILE *tfp; - long uptime; - if ((tfp = fopen("/proc/uptime", "r")) != NULL) { - if (fscanf(tfp, "%ld", &uptime) != 1) - uptime = -1; - fclose(tfp); - } - - if (uptime >= 0 && time(NULL) >= stb.st_mtime+uptime) { - fprintf(stderr, "rtacct: history is aged out, resetting\n"); - memset(hist_db, 0, sizeof(*hist_db)); - } - } - - close(fd); - } - - if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 && - (connect(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) == 0 - || (strcpy(sun.sun_path+1, "rtacct0"), - connect(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) == 0)) - && verify_forging(fd) == 0) { - nread(fd, (char*)kern_db, sizeof(*kern_db)); - if (hist_db && hist_db->signature[0] && - strcmp(kern_db->signature, hist_db->signature)) { - fprintf(stderr, "rtacct: history is stale, ignoring it.\n"); - hist_db = NULL; - } - close(fd); - } else { - if (fd >= 0) - close(fd); - - if (hist_db && hist_db->signature[0] && - strcmp(hist_db->signature, "kernel")) { - fprintf(stderr, "rtacct: history is stale, ignoring it.\n"); - hist_db = NULL; - } - - pad_kern_table(kern_db, read_kern_table(kern_db->ival)); - strcpy(kern_db->signature, "kernel"); - } - - if (ignore_history || hist_db == NULL) - dump_abs_db(stdout); - else - dump_incr_db(stdout); - - exit(0); -} diff --git a/misc/ss.c b/misc/ss.c deleted file mode 100644 index f902560..0000000 --- a/misc/ss.c +++ /dev/null @@ -1,2821 +0,0 @@ -/* - * ss.c "sockstat", socket statistics - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <netinet/in.h> -#include <string.h> -#include <errno.h> -#include <netdb.h> -#include <arpa/inet.h> -#include <resolv.h> -#include <dirent.h> -#include <fnmatch.h> -#include <getopt.h> - -#include "utils.h" -#include "rt_names.h" -#include "ll_map.h" -#include "libnetlink.h" -#include "SNAPSHOT.h" - -#include <linux/inet_diag.h> -#include <linux/tcp.h> -#include <net/tcp_states.h> - -int resolve_hosts = 0; -int resolve_services = 1; -int preferred_family = AF_UNSPEC; -int show_options = 0; -int show_details = 0; -int show_users = 0; -int show_mem = 0; -int show_tcpinfo = 0; - -int netid_width; -int state_width; -int addrp_width; -int addr_width; -int serv_width; -int screen_width; - -static const char *TCP_PROTO = "tcp"; -static const char *UDP_PROTO = "udp"; -static const char *RAW_PROTO = "raw"; -static const char *dg_proto = NULL; - -enum -{ - TCP_DB, - DCCP_DB, - UDP_DB, - RAW_DB, - UNIX_DG_DB, - UNIX_ST_DB, - PACKET_DG_DB, - PACKET_R_DB, - NETLINK_DB, - MAX_DB -}; - -#define PACKET_DBM ((1<<PACKET_DG_DB)|(1<<PACKET_R_DB)) -#define UNIX_DBM ((1<<UNIX_DG_DB)|(1<<UNIX_ST_DB)) -#define ALL_DB ((1<<MAX_DB)-1) - -enum { - SS_UNKNOWN, - SS_ESTABLISHED, - SS_SYN_SENT, - SS_SYN_RECV, - SS_FIN_WAIT1, - SS_FIN_WAIT2, - SS_TIME_WAIT, - SS_CLOSE, - SS_CLOSE_WAIT, - SS_LAST_ACK, - SS_LISTEN, - SS_CLOSING, - SS_MAX -}; - -#define SS_ALL ((1<<SS_MAX)-1) - -#include "ssfilter.h" - -struct filter -{ - int dbs; - int states; - int families; - struct ssfilter *f; -}; - -struct filter default_filter = { - dbs: (1<<TCP_DB), - states: SS_ALL & ~((1<<SS_LISTEN)|(1<<SS_CLOSE)|(1<<SS_TIME_WAIT)|(1<<SS_SYN_RECV)), - families: (1<<AF_INET)|(1<<AF_INET6), -}; - -struct filter current_filter; - -int generic_proc_open(char *env, char *name) -{ - char store[128]; - char *p = getenv(env); - if (!p) { - p = getenv("PROC_ROOT") ? : "/proc"; - snprintf(store, sizeof(store)-1, "%s/%s", p, name); - p = store; - } - return open(store, O_RDONLY); -} - -int net_tcp_open(void) -{ - return generic_proc_open("PROC_NET_TCP", "net/tcp"); -} - -int net_tcp6_open(void) -{ - return generic_proc_open("PROC_NET_TCP6", "net/tcp6"); -} - -int net_udp_open(void) -{ - return generic_proc_open("PROC_NET_UDP", "net/udp"); -} - -int net_udp6_open(void) -{ - return generic_proc_open("PROC_NET_UDP6", "net/udp6"); -} - -int net_raw_open(void) -{ - return generic_proc_open("PROC_NET_RAW", "net/raw"); -} - -int net_raw6_open(void) -{ - return generic_proc_open("PROC_NET_RAW6", "net/raw6"); -} - -int net_unix_open(void) -{ - return generic_proc_open("PROC_NET_UNIX", "net/unix"); -} - -int net_packet_open(void) -{ - return generic_proc_open("PROC_NET_PACKET", "net/packet"); -} - -int net_netlink_open(void) -{ - return generic_proc_open("PROC_NET_NETLINK", "net/netlink"); -} - -int slabinfo_open(void) -{ - return generic_proc_open("PROC_SLABINFO", "slabinfo"); -} - -int net_sockstat_open(void) -{ - return generic_proc_open("PROC_NET_SOCKSTAT", "net/sockstat"); -} - -int net_sockstat6_open(void) -{ - return generic_proc_open("PROC_NET_SOCKSTAT6", "net/sockstat6"); -} - -int net_snmp_open(void) -{ - return generic_proc_open("PROC_NET_SNMP", "net/snmp"); -} - -int net_netstat_open(void) -{ - return generic_proc_open("PROC_NET_NETSTAT", "net/netstat"); -} - -int ephemeral_ports_open(void) -{ - return generic_proc_open("PROC_IP_LOCAL_PORT_RANGE", "sys/net/ipv4/ip_local_port_range"); -} - -int find_users(int ino, char *buf, int buflen) -{ - char pattern[64]; - int pattern_len; - char *ptr = buf; - char name[1024]; - DIR *dir; - struct dirent *d; - int cnt = 0; - int nameoff; - - if (!ino) - return 0; - - sprintf(pattern, "socket:[%d]", ino); - pattern_len = strlen(pattern); - - strncpy(name, getenv("PROC_ROOT") ? : "/proc/", sizeof(name)/2); - name[sizeof(name)/2] = 0; - if (strlen(name) == 0 || - name[strlen(name)-1] != '/') - strcat(name, "/"); - nameoff = strlen(name); - if ((dir = opendir(name)) == NULL) - return 0; - - while ((d = readdir(dir)) != NULL) { - DIR *dir1; - struct dirent *d1; - int pid; - int pos; - char crap; - char process[16]; - - if (sscanf(d->d_name, "%d%c", &pid, &crap) != 1) - continue; - - sprintf(name+nameoff, "%d/fd/", pid); - pos = strlen(name); - if ((dir1 = opendir(name)) == NULL) - continue; - - process[0] = 0; - - while ((d1 = readdir(dir1)) != NULL) { - int fd, n; - char lnk[64]; - - if (sscanf(d1->d_name, "%d%c", &fd, &crap) != 1) - continue; - - sprintf(name+pos, "%d", fd); - n = readlink(name, lnk, sizeof(lnk)-1); - if (n != pattern_len || - memcmp(lnk, pattern, n)) - continue; - - if (ptr-buf >= buflen-1) - break; - - if (process[0] == 0) { - char tmp[1024]; - FILE *fp; - snprintf(tmp, sizeof(tmp), "%s/%d/stat", - getenv("PROC_ROOT") ? : "/proc", pid); - if ((fp = fopen(tmp, "r")) != NULL) { - fscanf(fp, "%*d (%[^)])", process); - fclose(fp); - } - } - - snprintf(ptr, buflen-(ptr-buf), "(\"%s\",%d,%d),", process, pid, fd); - ptr += strlen(ptr); - cnt++; - } - closedir(dir1); - } - closedir(dir); - if (ptr != buf) - ptr[-1] = 0; - return cnt; -} - - -/* Get stats from slab */ - -struct slabstat -{ - int socks; - int tcp_ports; - int tcp_tws; - int tcp_syns; - int skbs; -}; - -struct slabstat slabstat; - -static const char *slabstat_ids[] = -{ - "sock", - "tcp_bind_bucket", - "tcp_tw_bucket", - "tcp_open_request", - "skbuff_head_cache", -}; - -int get_slabstat(struct slabstat *s) -{ - char buf[256]; - FILE *fp; - int cnt; - - memset(s, 0, sizeof(*s)); - - if ((fp = fdopen(slabinfo_open(), "r")) == NULL) - return -1; - - cnt = sizeof(*s)/sizeof(int); - - fgets(buf, sizeof(buf), fp); - while(fgets(buf, sizeof(buf), fp) != NULL) { - int i; - for (i=0; i<sizeof(slabstat_ids)/sizeof(slabstat_ids[0]); i++) { - if (memcmp(buf, slabstat_ids[i], strlen(slabstat_ids[i])) == 0) { - sscanf(buf, "%*s%d", ((int *)s) + i); - cnt--; - break; - } - } - if (cnt <= 0) - break; - } - - fclose(fp); - return 0; -} - -static const char *sstate_name[] = { - "UNKNOWN", - [TCP_ESTABLISHED] = "ESTAB", - [TCP_SYN_SENT] = "SYN-SENT", - [TCP_SYN_RECV] = "SYN-RECV", - [TCP_FIN_WAIT1] = "FIN-WAIT-1", - [TCP_FIN_WAIT2] = "FIN-WAIT-2", - [TCP_TIME_WAIT] = "TIME-WAIT", - [TCP_CLOSE] = "UNCONN", - [TCP_CLOSE_WAIT] = "CLOSE-WAIT", - [TCP_LAST_ACK] = "LAST-ACK", - [TCP_LISTEN] = "LISTEN", - [TCP_CLOSING] = "CLOSING", -}; - -static const char *sstate_namel[] = { - "UNKNOWN", - [TCP_ESTABLISHED] = "established", - [TCP_SYN_SENT] = "syn-sent", - [TCP_SYN_RECV] = "syn-recv", - [TCP_FIN_WAIT1] = "fin-wait-1", - [TCP_FIN_WAIT2] = "fin-wait-2", - [TCP_TIME_WAIT] = "time-wait", - [TCP_CLOSE] = "unconnected", - [TCP_CLOSE_WAIT] = "close-wait", - [TCP_LAST_ACK] = "last-ack", - [TCP_LISTEN] = "listening", - [TCP_CLOSING] = "closing", -}; - -struct tcpstat -{ - inet_prefix local; - inet_prefix remote; - int lport; - int rport; - int state; - int rq, wq; - int timer; - int timeout; - int retrs; - int ino; - int probes; - int uid; - int refcnt; - unsigned long long sk; - int rto, ato, qack, cwnd, ssthresh; -}; - -static const char *tmr_name[] = { - "off", - "on", - "keepalive", - "timewait", - "persist", - "unknown" -}; - -const char *print_ms_timer(int timeout) -{ - static char buf[64]; - int secs, msecs, minutes; - if (timeout < 0) - timeout = 0; - secs = timeout/1000; - minutes = secs/60; - secs = secs%60; - msecs = timeout%1000; - buf[0] = 0; - if (minutes) { - msecs = 0; - snprintf(buf, sizeof(buf)-16, "%dmin", minutes); - if (minutes > 9) - secs = 0; - } - if (secs) { - if (secs > 9) - msecs = 0; - sprintf(buf+strlen(buf), "%d%s", secs, msecs ? "." : "sec"); - } - if (msecs) - sprintf(buf+strlen(buf), "%03dms", msecs); - return buf; -}; - -const char *print_hz_timer(int timeout) -{ - int hz = get_hz(); - return print_ms_timer(((timeout*1000) + hz-1)/hz); -}; - -struct scache -{ - struct scache *next; - int port; - char *name; - const char *proto; -}; - -struct scache *rlist; - -void init_service_resolver(void) -{ - char buf[128]; - FILE *fp = popen("/usr/sbin/rpcinfo -p 2>/dev/null", "r"); - if (fp) { - fgets(buf, sizeof(buf), fp); - while (fgets(buf, sizeof(buf), fp) != NULL) { - unsigned int progn, port; - char proto[128], prog[128]; - if (sscanf(buf, "%u %*d %s %u %s", &progn, proto, - &port, prog+4) == 4) { - struct scache *c = malloc(sizeof(*c)); - if (c) { - c->port = port; - memcpy(prog, "rpc.", 4); - c->name = strdup(prog); - if (strcmp(proto, TCP_PROTO) == 0) - c->proto = TCP_PROTO; - else if (strcmp(proto, UDP_PROTO) == 0) - c->proto = UDP_PROTO; - else - c->proto = NULL; - c->next = rlist; - rlist = c; - } - } - } - } -} - -static int ip_local_port_min, ip_local_port_max; - -/* Even do not try default linux ephemeral port ranges: - * default /etc/services contains so much of useless crap - * wouldbe "allocated" to this area that resolution - * is really harmful. I shrug each time when seeing - * "socks" or "cfinger" in dumps. - */ -static int is_ephemeral(int port) -{ - if (!ip_local_port_min) { - FILE *f = fdopen(ephemeral_ports_open(), "r"); - if (f) { - fscanf(f, "%d %d", - &ip_local_port_min, &ip_local_port_max); - fclose(f); - } else { - ip_local_port_min = 1024; - ip_local_port_max = 4999; - } - } - - return (port >= ip_local_port_min && port<= ip_local_port_max); -} - - -const char *__resolve_service(int port) -{ - struct scache *c; - - for (c = rlist; c; c = c->next) { - if (c->port == port && c->proto == dg_proto) - return c->name; - } - - if (!is_ephemeral(port)) { - static int notfirst; - struct servent *se; - if (!notfirst) { - setservent(1); - notfirst = 1; - } - se = getservbyport(htons(port), dg_proto); - if (se) - return se->s_name; - } - - return NULL; -} - - -const char *resolve_service(int port) -{ - static char buf[128]; - static struct scache cache[256]; - - if (port == 0) { - buf[0] = '*'; - buf[1] = 0; - return buf; - } - - if (resolve_services) { - if (dg_proto == RAW_PROTO) { - return inet_proto_n2a(port, buf, sizeof(buf)); - } else { - struct scache *c; - const char *res; - int hash = (port^(((unsigned long)dg_proto)>>2))&255; - - for (c = &cache[hash]; c; c = c->next) { - if (c->port == port && - c->proto == dg_proto) { - if (c->name) - return c->name; - goto do_numeric; - } - } - - if ((res = __resolve_service(port)) != NULL) { - if ((c = malloc(sizeof(*c))) == NULL) - goto do_numeric; - } else { - c = &cache[hash]; - if (c->name) - free(c->name); - } - c->port = port; - c->name = NULL; - c->proto = dg_proto; - if (res) { - c->name = strdup(res); - c->next = cache[hash].next; - cache[hash].next = c; - } - if (c->name) - return c->name; - } - } - - do_numeric: - sprintf(buf, "%u", port); - return buf; -} - -void formatted_print(const inet_prefix *a, int port) -{ - char buf[1024]; - const char *ap = buf; - int est_len; - - est_len = addr_width; - - if (a->family == AF_INET) { - if (a->data[0] == 0) { - buf[0] = '*'; - buf[1] = 0; - } else { - ap = format_host(AF_INET, 4, a->data, buf, sizeof(buf)); - } - } else { - ap = format_host(a->family, 16, a->data, buf, sizeof(buf)); - est_len = strlen(ap); - if (est_len <= addr_width) - est_len = addr_width; - else - est_len = addr_width + ((est_len-addr_width+3)/4)*4; - } - printf("%*s:%-*s ", est_len, ap, serv_width, resolve_service(port)); -} - -struct aafilter -{ - inet_prefix addr; - int port; - struct aafilter *next; -}; - -int inet2_addr_match(const inet_prefix *a, const inet_prefix *p, int plen) -{ - if (!inet_addr_match(a, p, plen)) - return 0; - - /* Cursed "v4 mapped" addresses: v4 mapped socket matches - * pure IPv4 rule, but v4-mapped rule selects only v4-mapped - * sockets. Fair? */ - if (p->family == AF_INET && a->family == AF_INET6) { - if (a->data[0] == 0 && a->data[1] == 0 && - a->data[2] == htonl(0xffff)) { - inet_prefix tmp = *a; - tmp.data[0] = a->data[3]; - return inet_addr_match(&tmp, p, plen); - } - } - return 1; -} - -int unix_match(const inet_prefix *a, const inet_prefix *p) -{ - char *addr, *pattern; - memcpy(&addr, a->data, sizeof(addr)); - memcpy(&pattern, p->data, sizeof(pattern)); - if (pattern == NULL) - return 1; - if (addr == NULL) - addr = ""; - return !fnmatch(pattern, addr, 0); -} - -int run_ssfilter(struct ssfilter *f, struct tcpstat *s) -{ - switch (f->type) { - case SSF_S_AUTO: - { - static int low, high=65535; - - if (s->local.family == AF_UNIX) { - char *p; - memcpy(&p, s->local.data, sizeof(p)); - return p == NULL || (p[0] == '@' && strlen(p) == 6 && - strspn(p+1, "0123456789abcdef") == 5); - } - if (s->local.family == AF_PACKET) - return s->lport == 0 && s->local.data == 0; - if (s->local.family == AF_NETLINK) - return s->lport < 0; - - if (!low) { - FILE *fp = fdopen(ephemeral_ports_open(), "r"); - if (fp) { - fscanf(fp, "%d%d", &low, &high); - fclose(fp); - } - } - return s->lport >= low && s->lport <= high; - } - case SSF_DCOND: - { - struct aafilter *a = (void*)f->pred; - if (a->addr.family == AF_UNIX) - return unix_match(&s->remote, &a->addr); - if (a->port != -1 && a->port != s->rport) - return 0; - if (a->addr.bitlen) { - do { - if (!inet2_addr_match(&s->remote, &a->addr, a->addr.bitlen)) - return 1; - } while ((a = a->next) != NULL); - return 0; - } - return 1; - } - case SSF_SCOND: - { - struct aafilter *a = (void*)f->pred; - if (a->addr.family == AF_UNIX) - return unix_match(&s->local, &a->addr); - if (a->port != -1 && a->port != s->lport) - return 0; - if (a->addr.bitlen) { - do { - if (!inet2_addr_match(&s->local, &a->addr, a->addr.bitlen)) - return 1; - } while ((a = a->next) != NULL); - return 0; - } - return 1; - } - case SSF_D_GE: - { - struct aafilter *a = (void*)f->pred; - return s->rport >= a->port; - } - case SSF_D_LE: - { - struct aafilter *a = (void*)f->pred; - return s->rport <= a->port; - } - case SSF_S_GE: - { - struct aafilter *a = (void*)f->pred; - return s->lport >= a->port; - } - case SSF_S_LE: - { - struct aafilter *a = (void*)f->pred; - return s->lport <= a->port; - } - - /* Yup. It is recursion. Sorry. */ - case SSF_AND: - return run_ssfilter(f->pred, s) && run_ssfilter(f->post, s); - case SSF_OR: - return run_ssfilter(f->pred, s) || run_ssfilter(f->post, s); - case SSF_NOT: - return !run_ssfilter(f->pred, s); - default: - abort(); - } -} - -/* Relocate external jumps by reloc. */ -static void ssfilter_patch(char *a, int len, int reloc) -{ - while (len > 0) { - struct inet_diag_bc_op *op = (struct inet_diag_bc_op*)a; - if (op->no == len+4) - op->no += reloc; - len -= op->yes; - a += op->yes; - } - if (len < 0) - abort(); -} - -static int ssfilter_bytecompile(struct ssfilter *f, char **bytecode) -{ - switch (f->type) { - case SSF_S_AUTO: - { - if (!(*bytecode=malloc(4))) abort(); - ((struct inet_diag_bc_op*)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_AUTO, 4, 8 }; - return 8; - } - case SSF_DCOND: - case SSF_SCOND: - { - struct aafilter *a = (void*)f->pred; - struct aafilter *b; - char *ptr; - int code = (f->type == SSF_DCOND ? INET_DIAG_BC_D_COND : INET_DIAG_BC_S_COND); - int len = 0; - - for (b=a; b; b=b->next) { - len += 4 + sizeof(struct inet_diag_hostcond); - if (a->addr.family == AF_INET6) - len += 16; - else - len += 4; - if (b->next) - len += 4; - } - if (!(ptr = malloc(len))) abort(); - *bytecode = ptr; - for (b=a; b; b=b->next) { - struct inet_diag_bc_op *op = (struct inet_diag_bc_op *)ptr; - int alen = (a->addr.family == AF_INET6 ? 16 : 4); - int oplen = alen + 4 + sizeof(struct inet_diag_hostcond); - struct inet_diag_hostcond *cond = (struct inet_diag_hostcond*)(ptr+4); - - *op = (struct inet_diag_bc_op){ code, oplen, oplen+4 }; - cond->family = a->addr.family; - cond->port = a->port; - cond->prefix_len = a->addr.bitlen; - memcpy(cond->addr, a->addr.data, alen); - ptr += oplen; - if (b->next) { - op = (struct inet_diag_bc_op *)ptr; - *op = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, len - (ptr-*bytecode)}; - ptr += 4; - } - } - return ptr - *bytecode; - } - case SSF_D_GE: - { - struct aafilter *x = (void*)f->pred; - if (!(*bytecode=malloc(8))) abort(); - ((struct inet_diag_bc_op*)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_GE, 8, 12 }; - ((struct inet_diag_bc_op*)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port }; - return 8; - } - case SSF_D_LE: - { - struct aafilter *x = (void*)f->pred; - if (!(*bytecode=malloc(8))) abort(); - ((struct inet_diag_bc_op*)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_D_LE, 8, 12 }; - ((struct inet_diag_bc_op*)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port }; - return 8; - } - case SSF_S_GE: - { - struct aafilter *x = (void*)f->pred; - if (!(*bytecode=malloc(8))) abort(); - ((struct inet_diag_bc_op*)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_GE, 8, 12 }; - ((struct inet_diag_bc_op*)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port }; - return 8; - } - case SSF_S_LE: - { - struct aafilter *x = (void*)f->pred; - if (!(*bytecode=malloc(8))) abort(); - ((struct inet_diag_bc_op*)*bytecode)[0] = (struct inet_diag_bc_op){ INET_DIAG_BC_S_LE, 8, 12 }; - ((struct inet_diag_bc_op*)*bytecode)[1] = (struct inet_diag_bc_op){ 0, 0, x->port }; - return 8; - } - - case SSF_AND: - { - char *a1, *a2, *a, l1, l2; - l1 = ssfilter_bytecompile(f->pred, &a1); - l2 = ssfilter_bytecompile(f->post, &a2); - if (!(a = malloc(l1+l2))) abort(); - memcpy(a, a1, l1); - memcpy(a+l1, a2, l2); - free(a1); free(a2); - ssfilter_patch(a, l1, l2); - *bytecode = a; - return l1+l2; - } - case SSF_OR: - { - char *a1, *a2, *a, l1, l2; - l1 = ssfilter_bytecompile(f->pred, &a1); - l2 = ssfilter_bytecompile(f->post, &a2); - if (!(a = malloc(l1+l2+4))) abort(); - memcpy(a, a1, l1); - memcpy(a+l1+4, a2, l2); - free(a1); free(a2); - *(struct inet_diag_bc_op*)(a+l1) = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, l2+4 }; - *bytecode = a; - return l1+l2+4; - } - case SSF_NOT: - { - char *a1, *a, l1; - l1 = ssfilter_bytecompile(f->pred, &a1); - if (!(a = malloc(l1+4))) abort(); - memcpy(a, a1, l1); - free(a1); - *(struct inet_diag_bc_op*)(a+l1) = (struct inet_diag_bc_op){ INET_DIAG_BC_JMP, 4, 8 }; - *bytecode = a; - return l1+4; - } - default: - abort(); - } -} - -static int remember_he(struct aafilter *a, struct hostent *he) -{ - char **ptr = he->h_addr_list; - int cnt = 0; - int len; - - if (he->h_addrtype == AF_INET) - len = 4; - else if (he->h_addrtype == AF_INET6) - len = 16; - else - return 0; - - while (*ptr) { - struct aafilter *b = a; - if (a->addr.bitlen) { - if ((b = malloc(sizeof(*b))) == NULL) - return cnt; - *b = *a; - b->next = a->next; - a->next = b; - } - memcpy(b->addr.data, *ptr, len); - b->addr.bytelen = len; - b->addr.bitlen = len*8; - b->addr.family = he->h_addrtype; - ptr++; - cnt++; - } - return cnt; -} - -static int get_dns_host(struct aafilter *a, const char *addr, int fam) -{ - static int notfirst; - int cnt = 0; - struct hostent *he; - - a->addr.bitlen = 0; - if (!notfirst) { - sethostent(1); - notfirst = 1; - } - he = gethostbyname2(addr, fam == AF_UNSPEC ? AF_INET : fam); - if (he) - cnt = remember_he(a, he); - if (fam == AF_UNSPEC) { - he = gethostbyname2(addr, AF_INET6); - if (he) - cnt += remember_he(a, he); - } - return !cnt; -} - -static int xll_initted = 0; - -static void xll_init(void) -{ - struct rtnl_handle rth; - rtnl_open(&rth, 0); - ll_init_map(&rth); - rtnl_close(&rth); - xll_initted = 1; -} - -static const char *xll_index_to_name(int index) -{ - if (!xll_initted) - xll_init(); - return ll_index_to_name(index); -} - -static int xll_name_to_index(const char *dev) -{ - if (!xll_initted) - xll_init(); - return ll_name_to_index(dev); -} - -void *parse_hostcond(char *addr) -{ - char *port = NULL; - struct aafilter a; - struct aafilter *res; - int fam = preferred_family; - - memset(&a, 0, sizeof(a)); - a.port = -1; - - if (fam == AF_UNIX || strncmp(addr, "unix:", 5) == 0) { - char *p; - a.addr.family = AF_UNIX; - if (strncmp(addr, "unix:", 5) == 0) - addr+=5; - p = strdup(addr); - a.addr.bitlen = 8*strlen(p); - memcpy(a.addr.data, &p, sizeof(p)); - goto out; - } - - if (fam == AF_PACKET || strncmp(addr, "link:", 5) == 0) { - a.addr.family = AF_PACKET; - a.addr.bitlen = 0; - if (strncmp(addr, "link:", 5) == 0) - addr+=5; - port = strchr(addr, ':'); - if (port) { - *port = 0; - if (port[1] && strcmp(port+1, "*")) { - if (get_integer(&a.port, port+1, 0)) { - if ((a.port = xll_name_to_index(port+1)) <= 0) - return NULL; - } - } - } - if (addr[0] && strcmp(addr, "*")) { - unsigned short tmp; - a.addr.bitlen = 32; - if (ll_proto_a2n(&tmp, addr)) - return NULL; - a.addr.data[0] = ntohs(tmp); - } - goto out; - } - - if (fam == AF_NETLINK || strncmp(addr, "netlink:", 8) == 0) { - a.addr.family = AF_NETLINK; - a.addr.bitlen = 0; - if (strncmp(addr, "netlink:", 8) == 0) - addr+=8; - port = strchr(addr, ':'); - if (port) { - *port = 0; - if (port[1] && strcmp(port+1, "*")) { - if (get_integer(&a.port, port+1, 0)) { - if (strcmp(port+1, "kernel") == 0) - a.port = 0; - else - return NULL; - } - } - } - if (addr[0] && strcmp(addr, "*")) { - a.addr.bitlen = 32; - if (get_u32(a.addr.data, addr, 0)) { - if (strcmp(addr, "rtnl") == 0) - a.addr.data[0] = 0; - else if (strcmp(addr, "fw") == 0) - a.addr.data[0] = 3; - else if (strcmp(addr, "tcpdiag") == 0) - a.addr.data[0] = 4; - else - return NULL; - } - } - goto out; - } - - if (strncmp(addr, "inet:", 5) == 0) { - addr += 5; - fam = AF_INET; - } else if (strncmp(addr, "inet6:", 6) == 0) { - addr += 6; - fam = AF_INET6; - } - - /* URL-like literal [] */ - if (addr[0] == '[') { - addr++; - if ((port = strchr(addr, ']')) == NULL) - return NULL; - *port++ = 0; - } else if (addr[0] == '*') { - port = addr+1; - } else { - port = strrchr(strchr(addr, '/') ? : addr, ':'); - } - if (port && *port) { - if (*port != ':') - return NULL; - *port++ = 0; - if (*port && *port != '*') { - if (get_integer(&a.port, port, 0)) { - struct servent *se1 = NULL; - struct servent *se2 = NULL; - if (current_filter.dbs&(1<<UDP_DB)) - se1 = getservbyname(port, UDP_PROTO); - if (current_filter.dbs&(1<<TCP_DB)) - se2 = getservbyname(port, TCP_PROTO); - if (se1 && se2 && se1->s_port != se2->s_port) { - fprintf(stderr, "Error: ambiguous port \"%s\".\n", port); - return NULL; - } - if (!se1) - se1 = se2; - if (se1) { - a.port = ntohs(se1->s_port); - } else { - struct scache *s; - for (s = rlist; s; s = s->next) { - if ((s->proto == UDP_PROTO && - (current_filter.dbs&(1<<UDP_DB))) || - (s->proto == TCP_PROTO && - (current_filter.dbs&(1<<TCP_DB)))) { - if (s->name && strcmp(s->name, port) == 0) { - if (a.port > 0 && a.port != s->port) { - fprintf(stderr, "Error: ambiguous port \"%s\".\n", port); - return NULL; - } - a.port = s->port; - } - } - } - if (a.port <= 0) { - fprintf(stderr, "Error: \"%s\" does not look like a port.\n", port); - return NULL; - } - } - } - } - } - if (addr && *addr && *addr != '*') { - if (get_prefix_1(&a.addr, addr, fam)) { - if (get_dns_host(&a, addr, fam)) { - fprintf(stderr, "Error: an inet prefix is expected rather than \"%s\".\n", addr); - return NULL; - } - } - } - - out: - res = malloc(sizeof(*res)); - if (res) - memcpy(res, &a, sizeof(a)); - return res; -} - -static int tcp_show_line(char *line, struct filter *f, int family) -{ - struct tcpstat s; - char *loc, *rem, *data; - char opt[256]; - int n; - char *p; - - if ((p = strchr(line, ':')) == NULL) - return -1; - loc = p+2; - - if ((p = strchr(loc, ':')) == NULL) - return -1; - p[5] = 0; - rem = p+6; - - if ((p = strchr(rem, ':')) == NULL) - return -1; - p[5] = 0; - data = p+6; - - do { - int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0'); - - if (!(f->states & (1<<state))) - return 0; - } while (0); - - s.local.family = s.remote.family = family; - if (family == AF_INET) { - sscanf(loc, "%x:%x", s.local.data, (unsigned*)&s.lport); - sscanf(rem, "%x:%x", s.remote.data, (unsigned*)&s.rport); - s.local.bytelen = s.remote.bytelen = 4; - } else { - sscanf(loc, "%08x%08x%08x%08x:%x", - s.local.data, - s.local.data+1, - s.local.data+2, - s.local.data+3, - &s.lport); - sscanf(rem, "%08x%08x%08x%08x:%x", - s.remote.data, - s.remote.data+1, - s.remote.data+2, - s.remote.data+3, - &s.rport); - s.local.bytelen = s.remote.bytelen = 16; - } - - if (f->f && run_ssfilter(f->f, &s) == 0) - return 0; - - opt[0] = 0; - n = sscanf(data, "%x %x:%x %x:%x %x %d %d %d %d %llx %d %d %d %d %d %[^\n]\n", - &s.state, &s.wq, &s.rq, - &s.timer, &s.timeout, &s.retrs, &s.uid, &s.probes, &s.ino, - &s.refcnt, &s.sk, &s.rto, &s.ato, &s.qack, - &s.cwnd, &s.ssthresh, opt); - - if (n < 17) - opt[0] = 0; - - if (n < 12) { - s.rto = 0; - s.cwnd = 2; - s.ssthresh = -1; - s.ato = s.qack = 0; - } - - if (netid_width) - printf("%-*s ", netid_width, "tcp"); - if (state_width) - printf("%-*s ", state_width, sstate_name[s.state]); - - printf("%-6d %-6d ", s.rq, s.wq); - - formatted_print(&s.local, s.lport); - formatted_print(&s.remote, s.rport); - - if (show_options) { - if (s.timer) { - if (s.timer > 4) - s.timer = 5; - printf(" timer:(%s,%s,%d)", - tmr_name[s.timer], - print_hz_timer(s.timeout), - s.timer != 1 ? s.probes : s.retrs); - } - } - if (show_tcpinfo) { - if (s.rto && s.rto != 3*get_hz()) - printf(" rto:%g", (double)s.rto/get_hz()); - if (s.ato) - printf(" ato:%g", (double)s.ato/get_hz()); - if (s.cwnd != 2) - printf(" cwnd:%d", s.cwnd); - if (s.ssthresh != -1) - printf(" ssthresh:%d", s.ssthresh); - if (s.qack/2) - printf(" qack:%d", s.qack/2); - if (s.qack&1) - printf(" bidir"); - } - if (show_users) { - char ubuf[4096]; - if (find_users(s.ino, ubuf, sizeof(ubuf)) > 0) - printf(" users:(%s)", ubuf); - } - if (show_details) { - if (s.uid) - printf(" uid:%u", (unsigned)s.uid); - printf(" ino:%u", (unsigned)s.ino); - printf(" sk:%llx", s.sk); - if (opt[0]) - printf(" opt:\"%s\"", opt); - } - printf("\n"); - - return 0; -} - -static int generic_record_read(int fd, char *buf, int bufsize, - int (*worker)(char*, struct filter *, int), - struct filter *f, int fam) -{ - int n; - int recsize; - int eof = 0; - char *p; - - /* Load the first chunk and calculate record length from it. */ - n = read(fd, buf, bufsize); - if (n < 0) - goto outerr; - /* I _know_ that this is wrong, do not remind. :-) - * But this works nowadays. */ - if (n < bufsize) - eof = 1; - p = memchr(buf, '\n', n); - if (p == NULL || (p-buf) >= n) - goto outwrongformat; - recsize = (p-buf)+1; - p = buf+recsize; - - for (;;) { - while ((p+recsize) - buf <= n) { - if (p[recsize-1] != '\n') - goto outwrongformat; - p[recsize-1] = 0; - if (worker(p, f, fam) < 0) - goto done; - p += recsize; - } - if (!eof) { - int remains = (buf+bufsize) - p; - memcpy(buf, p, remains); - p = buf+remains; - n = read(fd, p, (buf+bufsize) - p); - if (n < 0) - goto outerr; - if (n < (buf+bufsize) - p) { - eof = 1; - if (n == 0) { - if (remains) - goto outwrongformat; - goto done; - } - } - n += remains; - p = buf; - } else { - if (p != buf+n) - goto outwrongformat; - goto done; - } - } -done: - return 0; - -outwrongformat: - errno = EINVAL; -outerr: - return -1; -} - -static char *sprint_bw(char *buf, double bw) -{ - if (bw > 1000000.) - sprintf(buf,"%.1fM", bw / 1000000.); - else if (bw > 1000.) - sprintf(buf,"%.1fK", bw / 1000.); - else - sprintf(buf, "%g", bw); - - return buf; -} - -static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r) -{ - struct rtattr * tb[INET_DIAG_MAX+1]; - char b1[64]; - double rtt = 0; - - parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr*)(r+1), - nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); - - if (tb[INET_DIAG_MEMINFO]) { - const struct inet_diag_meminfo *minfo - = RTA_DATA(tb[INET_DIAG_MEMINFO]); - printf(" mem:(r%u,w%u,f%u,t%u)", - minfo->idiag_rmem, - minfo->idiag_wmem, - minfo->idiag_fmem, - minfo->idiag_tmem); - } - - if (tb[INET_DIAG_INFO]) { - struct tcp_info *info; - int len = RTA_PAYLOAD(tb[INET_DIAG_INFO]); - - /* workaround for older kernels with less fields */ - if (len < sizeof(*info)) { - info = alloca(sizeof(*info)); - memset(info, 0, sizeof(*info)); - memcpy(info, RTA_DATA(tb[INET_DIAG_INFO]), len); - } else - info = RTA_DATA(tb[INET_DIAG_INFO]); - - if (show_options) { - if (info->tcpi_options & TCPI_OPT_TIMESTAMPS) - printf(" ts"); - if (info->tcpi_options & TCPI_OPT_SACK) - printf(" sack"); - if (info->tcpi_options & TCPI_OPT_ECN) - printf(" ecn"); - } - - if (tb[INET_DIAG_CONG]) - printf("%s", (char *) RTA_DATA(tb[INET_DIAG_CONG])); - - if (info->tcpi_options & TCPI_OPT_WSCALE) - printf(" wscale:%d,%d", info->tcpi_snd_wscale, - info->tcpi_rcv_wscale); - if (info->tcpi_rto && info->tcpi_rto != 3000000) - printf(" rto:%g", (double)info->tcpi_rto/1000); - if (info->tcpi_rtt) - printf(" rtt:%g/%g", (double)info->tcpi_rtt/1000, - (double)info->tcpi_rttvar/1000); - if (info->tcpi_ato) - printf(" ato:%g", (double)info->tcpi_ato/1000); - if (info->tcpi_snd_cwnd != 2) - printf(" cwnd:%d", info->tcpi_snd_cwnd); - if (info->tcpi_snd_ssthresh < 0xFFFF) - printf(" ssthresh:%d", info->tcpi_snd_ssthresh); - - rtt = (double) info->tcpi_rtt; - if (tb[INET_DIAG_VEGASINFO]) { - const struct tcpvegas_info *vinfo - = RTA_DATA(tb[INET_DIAG_VEGASINFO]); - - if (vinfo->tcpv_enabled && - vinfo->tcpv_rtt && vinfo->tcpv_rtt != 0x7fffffff) - rtt = vinfo->tcpv_rtt; - } - - if (rtt > 0 && info->tcpi_snd_mss && info->tcpi_snd_cwnd) { - printf(" send %sbps", - sprint_bw(b1, (double) info->tcpi_snd_cwnd * - (double) info->tcpi_snd_mss * 8000000. - / rtt)); - } - - if (info->tcpi_rcv_rtt) - printf(" rcv_rtt:%g", (double) info->tcpi_rcv_rtt/1000); - if (info->tcpi_rcv_space) - printf(" rcv_space:%d", info->tcpi_rcv_space); - - } -} - -int tcp_show_sock(struct nlmsghdr *nlh, struct filter *f) -{ - struct inet_diag_msg *r = NLMSG_DATA(nlh); - struct tcpstat s; - - s.state = r->idiag_state; - s.local.family = s.remote.family = r->idiag_family; - s.lport = ntohs(r->id.idiag_sport); - s.rport = ntohs(r->id.idiag_dport); - if (s.local.family == AF_INET) { - s.local.bytelen = s.remote.bytelen = 4; - } else { - s.local.bytelen = s.remote.bytelen = 16; - } - memcpy(s.local.data, r->id.idiag_src, s.local.bytelen); - memcpy(s.remote.data, r->id.idiag_dst, s.local.bytelen); - - if (f && f->f && run_ssfilter(f->f, &s) == 0) - return 0; - - if (netid_width) - printf("%-*s ", netid_width, "tcp"); - if (state_width) - printf("%-*s ", state_width, sstate_name[s.state]); - - printf("%-6d %-6d ", r->idiag_rqueue, r->idiag_wqueue); - - formatted_print(&s.local, s.lport); - formatted_print(&s.remote, s.rport); - - if (show_options) { - if (r->idiag_timer) { - if (r->idiag_timer > 4) - r->idiag_timer = 5; - printf(" timer:(%s,%s,%d)", - tmr_name[r->idiag_timer], - print_ms_timer(r->idiag_expires), - r->idiag_retrans); - } - } - if (show_users) { - char ubuf[4096]; - if (find_users(r->idiag_inode, ubuf, sizeof(ubuf)) > 0) - printf(" users:(%s)", ubuf); - } - if (show_details) { - if (r->idiag_uid) - printf(" uid:%u", (unsigned)r->idiag_uid); - printf(" ino:%u", (unsigned)r->idiag_inode); - printf(" sk:%08x", r->id.idiag_cookie[0]); - if (r->id.idiag_cookie[1] != 0) - printf("%08x", r->id.idiag_cookie[1]); - } - if (show_mem || show_tcpinfo) { - printf("\n\t"); - tcp_show_info(nlh, r); - } - - printf("\n"); - - return 0; -} - -int tcp_show_netlink(struct filter *f, FILE *dump_fp, int socktype) -{ - int fd; - struct sockaddr_nl nladdr; - struct { - struct nlmsghdr nlh; - struct inet_diag_req r; - } req; - char *bc = NULL; - int bclen; - struct msghdr msg; - struct rtattr rta; - char buf[8192]; - struct iovec iov[3]; - - if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG)) < 0) - return -1; - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - - req.nlh.nlmsg_len = sizeof(req); - req.nlh.nlmsg_type = socktype; - req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; - req.nlh.nlmsg_pid = 0; - req.nlh.nlmsg_seq = 123456; - memset(&req.r, 0, sizeof(req.r)); - req.r.idiag_family = AF_INET; - req.r.idiag_states = f->states; - if (show_mem) - req.r.idiag_ext |= (1<<(INET_DIAG_MEMINFO-1)); - - if (show_tcpinfo) { - req.r.idiag_ext |= (1<<(INET_DIAG_INFO-1)); - req.r.idiag_ext |= (1<<(INET_DIAG_VEGASINFO-1)); - req.r.idiag_ext |= (1<<(INET_DIAG_CONG-1)); - } - - iov[0] = (struct iovec){ - .iov_base = &req, - .iov_len = sizeof(req) - }; - if (f->f) { - bclen = ssfilter_bytecompile(f->f, &bc); - rta.rta_type = INET_DIAG_REQ_BYTECODE; - rta.rta_len = RTA_LENGTH(bclen); - iov[1] = (struct iovec){ &rta, sizeof(rta) }; - iov[2] = (struct iovec){ bc, bclen }; - req.nlh.nlmsg_len += RTA_LENGTH(bclen); - } - - msg = (struct msghdr) { - .msg_name = (void*)&nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = iov, - .msg_iovlen = f->f ? 3 : 1, - }; - - if (sendmsg(fd, &msg, 0) < 0) - return -1; - - iov[0] = (struct iovec){ - .iov_base = buf, - .iov_len = sizeof(buf) - }; - - while (1) { - int status; - struct nlmsghdr *h; - - msg = (struct msghdr) { - (void*)&nladdr, sizeof(nladdr), - iov, 1, - NULL, 0, - 0 - }; - - status = recvmsg(fd, &msg, 0); - - if (status < 0) { - if (errno == EINTR) - continue; - perror("OVERRUN"); - continue; - } - if (status == 0) { - fprintf(stderr, "EOF on netlink\n"); - return 0; - } - - if (dump_fp) - fwrite(buf, 1, NLMSG_ALIGN(status), dump_fp); - - h = (struct nlmsghdr*)buf; - while (NLMSG_OK(h, status)) { - int err; - - if (/*h->nlmsg_pid != rth->local.nl_pid ||*/ - h->nlmsg_seq != 123456) - goto skip_it; - - if (h->nlmsg_type == NLMSG_DONE) - return 0; - if (h->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); - if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { - fprintf(stderr, "ERROR truncated\n"); - } else { - errno = -err->error; - perror("TCPDIAG answers"); - } - return 0; - } - if (!dump_fp) { - err = tcp_show_sock(h, NULL); - if (err < 0) - return err; - } - -skip_it: - h = NLMSG_NEXT(h, status); - } - if (msg.msg_flags & MSG_TRUNC) { - fprintf(stderr, "Message truncated\n"); - continue; - } - if (status) { - fprintf(stderr, "!!!Remnant of size %d\n", status); - exit(1); - } - } - return 0; -} - -int tcp_show_netlink_file(struct filter *f) -{ - FILE *fp; - char buf[8192]; - - if ((fp = fopen(getenv("TCPDIAG_FILE"), "r")) == NULL) { - perror("fopen($TCPDIAG_FILE)"); - return -1; - } - - while (1) { - int status, err; - struct nlmsghdr *h = (struct nlmsghdr*)buf; - - status = fread(buf, 1, sizeof(*h), fp); - if (status < 0) { - perror("Reading header from $TCPDIAG_FILE"); - return -1; - } - if (status != sizeof(*h)) { - perror("Unexpected EOF reading $TCPDIAG_FILE"); - return -1; - } - - status = fread(h+1, 1, NLMSG_ALIGN(h->nlmsg_len-sizeof(*h)), fp); - - if (status < 0) { - perror("Reading $TCPDIAG_FILE"); - return -1; - } - if (status + sizeof(*h) < h->nlmsg_len) { - perror("Unexpected EOF reading $TCPDIAG_FILE"); - return -1; - } - - /* The only legal exit point */ - if (h->nlmsg_type == NLMSG_DONE) - return 0; - - if (h->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); - if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { - fprintf(stderr, "ERROR truncated\n"); - } else { - errno = -err->error; - perror("TCPDIAG answered"); - } - return -1; - } - - err = tcp_show_sock(h, f); - if (err < 0) - return err; - } -} - -int tcp_show(struct filter *f, int socktype) -{ - int fd = -1; - char *buf = NULL; - int bufsize = 64*1024; - - dg_proto = TCP_PROTO; - - if (getenv("TCPDIAG_FILE")) - return tcp_show_netlink_file(f); - - if (!getenv("PROC_NET_TCP") && !getenv("PROC_ROOT") - && tcp_show_netlink(f, NULL, socktype) == 0) - return 0; - - /* Sigh... We have to parse /proc/net/tcp... */ - - /* Estimate amount of sockets and try to allocate - * huge buffer to read all the table at one read. - * Limit it by 16MB though. The assumption is: as soon as - * kernel was able to hold information about N connections, - * it is able to give us some memory for snapshot. - */ - if (1) { - int guess = slabstat.socks+slabstat.tcp_syns; - if (f->states&(1<<SS_TIME_WAIT)) - guess += slabstat.tcp_tws; - if (guess > (16*1024*1024)/128) - guess = (16*1024*1024)/128; - guess *= 128; - if (guess > bufsize) - bufsize = guess; - } - while (bufsize >= 64*1024) { - if ((buf = malloc(bufsize)) != NULL) - break; - bufsize /= 2; - } - if (buf == NULL) { - errno = ENOMEM; - return -1; - } - - if (f->families & (1<<AF_INET)) { - if ((fd = net_tcp_open()) < 0) - goto outerr; - if (generic_record_read(fd, buf, bufsize, tcp_show_line, f, AF_INET)) - goto outerr; - close(fd); - } - - if ((f->families & (1<<AF_INET6)) && - (fd = net_tcp6_open()) >= 0) { - if (generic_record_read(fd, buf, bufsize, tcp_show_line, f, AF_INET6)) - goto outerr; - close(fd); - } - - free(buf); - return 0; - -outerr: - do { - int saved_errno = errno; - if (buf) - free(buf); - if (fd >= 0) - close(fd); - errno = saved_errno; - return -1; - } while (0); -} - - -int dgram_show_line(char *line, struct filter *f, int family) -{ - struct tcpstat s; - char *loc, *rem, *data; - char opt[256]; - int n; - char *p; - - if ((p = strchr(line, ':')) == NULL) - return -1; - loc = p+2; - - if ((p = strchr(loc, ':')) == NULL) - return -1; - p[5] = 0; - rem = p+6; - - if ((p = strchr(rem, ':')) == NULL) - return -1; - p[5] = 0; - data = p+6; - - do { - int state = (data[1] >= 'A') ? (data[1] - 'A' + 10) : (data[1] - '0'); - - if (!(f->states & (1<<state))) - return 0; - } while (0); - - s.local.family = s.remote.family = family; - if (family == AF_INET) { - sscanf(loc, "%x:%x", s.local.data, (unsigned*)&s.lport); - sscanf(rem, "%x:%x", s.remote.data, (unsigned*)&s.rport); - s.local.bytelen = s.remote.bytelen = 4; - } else { - sscanf(loc, "%08x%08x%08x%08x:%x", - s.local.data, - s.local.data+1, - s.local.data+2, - s.local.data+3, - &s.lport); - sscanf(rem, "%08x%08x%08x%08x:%x", - s.remote.data, - s.remote.data+1, - s.remote.data+2, - s.remote.data+3, - &s.rport); - s.local.bytelen = s.remote.bytelen = 16; - } - - if (f->f && run_ssfilter(f->f, &s) == 0) - return 0; - - opt[0] = 0; - n = sscanf(data, "%x %x:%x %*x:%*x %*x %d %*d %d %d %llx %[^\n]\n", - &s.state, &s.wq, &s.rq, - &s.uid, &s.ino, - &s.refcnt, &s.sk, opt); - - if (n < 9) - opt[0] = 0; - - if (netid_width) - printf("%-*s ", netid_width, dg_proto); - if (state_width) - printf("%-*s ", state_width, sstate_name[s.state]); - - printf("%-6d %-6d ", s.rq, s.wq); - - formatted_print(&s.local, s.lport); - formatted_print(&s.remote, s.rport); - - if (show_users) { - char ubuf[4096]; - if (find_users(s.ino, ubuf, sizeof(ubuf)) > 0) - printf(" users:(%s)", ubuf); - } - - if (show_details) { - if (s.uid) - printf(" uid=%u", (unsigned)s.uid); - printf(" ino=%u", (unsigned)s.ino); - printf(" sk=%llx", s.sk); - if (opt[0]) - printf(" opt:\"%s\"", opt); - } - printf("\n"); - - return 0; -} - - -int udp_show(struct filter *f) -{ - int fd = -1; - char buf[8192]; - int bufsize = sizeof(buf); - - dg_proto = UDP_PROTO; - - if (f->families&(1<<AF_INET)) { - if ((fd = net_udp_open()) < 0) - goto outerr; - if (generic_record_read(fd, buf, bufsize, dgram_show_line, f, AF_INET)) - goto outerr; - close(fd); - } - - if ((f->families&(1<<AF_INET6)) && - (fd = net_udp6_open()) >= 0) { - if (generic_record_read(fd, buf, bufsize, dgram_show_line, f, AF_INET6)) - goto outerr; - close(fd); - } - return 0; - -outerr: - do { - int saved_errno = errno; - if (fd >= 0) - close(fd); - errno = saved_errno; - return -1; - } while (0); -} - -int raw_show(struct filter *f) -{ - int fd = -1; - char buf[8192]; - int bufsize = sizeof(buf); - - dg_proto = RAW_PROTO; - - if (f->families&(1<<AF_INET)) { - if ((fd = net_raw_open()) < 0) - goto outerr; - if (generic_record_read(fd, buf, bufsize, dgram_show_line, f, AF_INET)) - goto outerr; - close(fd); - } - - if ((f->families&(1<<AF_INET6)) && - (fd = net_raw6_open()) >= 0) { - if (generic_record_read(fd, buf, bufsize, dgram_show_line, f, AF_INET6)) - goto outerr; - close(fd); - } - return 0; - -outerr: - do { - int saved_errno = errno; - if (fd >= 0) - close(fd); - errno = saved_errno; - return -1; - } while (0); -} - - -struct unixstat -{ - struct unixstat *next; - int ino; - int peer; - int rq; - int wq; - int state; - int type; - char *name; -}; - - - -int unix_state_map[] = { SS_CLOSE, SS_SYN_SENT, - SS_ESTABLISHED, SS_CLOSING }; - - -#define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct unixstat)) - -void unix_list_free(struct unixstat *list) -{ - while (list) { - struct unixstat *s = list; - list = list->next; - if (s->name) - free(s->name); - free(s); - } -} - -void unix_list_print(struct unixstat *list, struct filter *f) -{ - struct unixstat *s; - char *peer; - - for (s = list; s; s = s->next) { - if (!(f->states & (1<<s->state))) - continue; - if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB))) - continue; - if (s->type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB))) - continue; - - peer = "*"; - if (s->peer) { - struct unixstat *p; - for (p = list; p; p = p->next) { - if (s->peer == p->ino) - break; - } - if (!p) { - peer = "?"; - } else { - peer = p->name ? : "*"; - } - } - - if (f->f) { - struct tcpstat tst; - tst.local.family = AF_UNIX; - tst.remote.family = AF_UNIX; - memcpy(tst.local.data, &s->name, sizeof(s->name)); - if (strcmp(peer, "*") == 0) - memset(tst.remote.data, 0, sizeof(peer)); - else - memcpy(tst.remote.data, &peer, sizeof(peer)); - if (run_ssfilter(f->f, &tst) == 0) - continue; - } - - if (netid_width) - printf("%-*s ", netid_width, - s->type == SOCK_STREAM ? "u_str" : "u_dgr"); - if (state_width) - printf("%-*s ", state_width, sstate_name[s->state]); - printf("%-6d %-6d ", s->rq, s->wq); - printf("%*s %-*d %*s %-*d", - addr_width, s->name ? : "*", serv_width, s->ino, - addr_width, peer, serv_width, s->peer); - if (show_users) { - char ubuf[4096]; - if (find_users(s->ino, ubuf, sizeof(ubuf)) > 0) - printf(" users:(%s)", ubuf); - } - printf("\n"); - } -} - -int unix_show(struct filter *f) -{ - FILE *fp; - char buf[256]; - char name[128]; - int newformat = 0; - int cnt; - struct unixstat *list = NULL; - - if ((fp = fdopen(net_unix_open(), "r")) == NULL) - return -1; - fgets(buf, sizeof(buf)-1, fp); - - if (memcmp(buf, "Peer", 4) == 0) - newformat = 1; - cnt = 0; - - while (fgets(buf, sizeof(buf)-1, fp)) { - struct unixstat *u, **insp; - int flags; - - if (!(u = malloc(sizeof(*u)))) - break; - u->name = NULL; - - if (sscanf(buf, "%x: %x %x %x %x %x %d %s", - &u->peer, &u->rq, &u->wq, &flags, &u->type, - &u->state, &u->ino, name) < 8) - name[0] = 0; - - if (flags&(1<<16)) { - u->state = SS_LISTEN; - } else { - u->state = unix_state_map[u->state-1]; - if (u->type == SOCK_DGRAM && - u->state == SS_CLOSE && - u->peer) - u->state = SS_ESTABLISHED; - } - - if (!newformat) { - u->peer = 0; - u->rq = 0; - u->wq = 0; - } - - insp = &list; - while (*insp) { - if (u->type < (*insp)->type || - (u->type == (*insp)->type && - u->ino < (*insp)->ino)) - break; - insp = &(*insp)->next; - } - u->next = *insp; - *insp = u; - - if (name[0]) { - if ((u->name = malloc(strlen(name)+1)) == NULL) - break; - strcpy(u->name, name); - } - if (++cnt > MAX_UNIX_REMEMBER) { - unix_list_print(list, f); - unix_list_free(list); - list = NULL; - cnt = 0; - } - } - - if (list) { - unix_list_print(list, f); - unix_list_free(list); - list = NULL; - cnt = 0; - } - - return 0; -} - - -int packet_show(struct filter *f) -{ - FILE *fp; - char buf[256]; - int type; - int prot; - int iface; - int state; - int rq; - int uid; - int ino; - unsigned long long sk; - - if (!(f->states & (1<<SS_CLOSE))) - return 0; - - if ((fp = fdopen(net_packet_open(), "r")) == NULL) - return -1; - fgets(buf, sizeof(buf)-1, fp); - - while (fgets(buf, sizeof(buf)-1, fp)) { - sscanf(buf, "%llx %*d %d %x %d %d %u %u %u", - &sk, - &type, &prot, &iface, &state, - &rq, &uid, &ino); - - if (type == SOCK_RAW && !(f->dbs&(1<<PACKET_R_DB))) - continue; - if (type == SOCK_DGRAM && !(f->dbs&(1<<PACKET_DG_DB))) - continue; - if (f->f) { - struct tcpstat tst; - tst.local.family = AF_PACKET; - tst.remote.family = AF_PACKET; - tst.rport = 0; - tst.lport = iface; - tst.local.data[0] = prot; - tst.remote.data[0] = 0; - if (run_ssfilter(f->f, &tst) == 0) - continue; - } - - if (netid_width) - printf("%-*s ", netid_width, - type == SOCK_RAW ? "p_raw" : "p_dgr"); - if (state_width) - printf("%-*s ", state_width, "UNCONN"); - printf("%-6d %-6d ", rq, 0); - if (prot == 3) { - printf("%*s:", addr_width, "*"); - } else { - char tb[16]; - printf("%*s:", addr_width, - ll_proto_n2a(htons(prot), tb, sizeof(tb))); - } - if (iface == 0) { - printf("%-*s ", serv_width, "*"); - } else { - printf("%-*s ", serv_width, xll_index_to_name(iface)); - } - printf("%*s*%-*s", - addr_width, "", serv_width, ""); - - if (show_users) { - char ubuf[4096]; - if (find_users(ino, ubuf, sizeof(ubuf)) > 0) - printf(" users:(%s)", ubuf); - } - if (show_details) { - printf(" ino=%u uid=%u sk=%llx", ino, uid, sk); - } - printf("\n"); - } - - return 0; -} - -int netlink_show(struct filter *f) -{ - FILE *fp; - char buf[256]; - int prot, pid; - unsigned groups; - int rq, wq, rc; - unsigned long long sk, cb; - - if (!(f->states & (1<<SS_CLOSE))) - return 0; - - if ((fp = fdopen(net_netlink_open(), "r")) == NULL) - return -1; - fgets(buf, sizeof(buf)-1, fp); - - while (fgets(buf, sizeof(buf)-1, fp)) { - sscanf(buf, "%llx %d %d %x %d %d %llx %d", - &sk, - &prot, &pid, &groups, &rq, &wq, &cb, &rc); - - if (f->f) { - struct tcpstat tst; - tst.local.family = AF_NETLINK; - tst.remote.family = AF_NETLINK; - tst.rport = -1; - tst.lport = pid; - tst.local.data[0] = prot; - tst.remote.data[0] = 0; - if (run_ssfilter(f->f, &tst) == 0) - continue; - } - - if (netid_width) - printf("%-*s ", netid_width, "nl"); - if (state_width) - printf("%-*s ", state_width, "UNCONN"); - printf("%-6d %-6d ", rq, wq); - if (resolve_services && prot == 0) - printf("%*s:", addr_width, "rtnl"); - else if (resolve_services && prot == 3) - printf("%*s:", addr_width, "fw"); - else if (resolve_services && prot == 4) - printf("%*s:", addr_width, "tcpdiag"); - else - printf("%*d:", addr_width, prot); - if (pid == -1) { - printf("%-*s ", serv_width, "*"); - } else if (resolve_services) { - int done = 0; - if (!pid) { - done = 1; - printf("%-*s ", serv_width, "kernel"); - } else if (pid > 0) { - char procname[64]; - FILE *fp; - sprintf(procname, "%s/%d/stat", - getenv("PROC_ROOT") ? : "/proc", pid); - if ((fp = fopen(procname, "r")) != NULL) { - if (fscanf(fp, "%*d (%[^)])", procname) == 1) { - sprintf(procname+strlen(procname), "/%d", pid); - printf("%-*s ", serv_width, procname); - done = 1; - } - fclose(fp); - } - } - if (!done) - printf("%-*d ", serv_width, pid); - } else { - printf("%-*d ", serv_width, pid); - } - printf("%*s*%-*s", - addr_width, "", serv_width, ""); - - if (show_details) { - printf(" sk=%llx cb=%llx groups=0x%08x", sk, cb, groups); - } - printf("\n"); - } - - return 0; -} - -struct snmpstat -{ - int tcp_estab; -}; - -int get_snmp_int(char *proto, char *key, int *result) -{ - char buf[1024]; - FILE *fp; - int protolen = strlen(proto); - int keylen = strlen(key); - - *result = 0; - - if ((fp = fdopen(net_snmp_open(), "r")) == NULL) - return -1; - - while (fgets(buf, sizeof(buf), fp) != NULL) { - char *p = buf; - int pos = 0; - if (memcmp(buf, proto, protolen)) - continue; - while ((p = strchr(p, ' ')) != NULL) { - pos++; - p++; - if (memcmp(p, key, keylen) == 0 && - (p[keylen] == ' ' || p[keylen] == '\n')) - break; - } - if (fgets(buf, sizeof(buf), fp) == NULL) - break; - if (memcmp(buf, proto, protolen)) - break; - p = buf; - while ((p = strchr(p, ' ')) != NULL) { - p++; - if (--pos == 0) { - sscanf(p, "%d", result); - fclose(fp); - return 0; - } - } - } - - fclose(fp); - errno = ESRCH; - return -1; -} - - -/* Get stats from sockstat */ - -struct sockstat -{ - int socks; - int tcp_mem; - int tcp_total; - int tcp_orphans; - int tcp_tws; - int tcp4_hashed; - int udp4; - int raw4; - int frag4; - int frag4_mem; - int tcp6_hashed; - int udp6; - int raw6; - int frag6; - int frag6_mem; -}; - -static void get_sockstat_line(char *line, struct sockstat *s) -{ - char id[256], rem[256]; - - if (sscanf(line, "%[^ ] %[^\n]\n", id, rem) != 2) - return; - - if (strcmp(id, "sockets:") == 0) - sscanf(rem, "%*s%d", &s->socks); - else if (strcmp(id, "UDP:") == 0) - sscanf(rem, "%*s%d", &s->udp4); - else if (strcmp(id, "UDP6:") == 0) - sscanf(rem, "%*s%d", &s->udp6); - else if (strcmp(id, "RAW:") == 0) - sscanf(rem, "%*s%d", &s->raw4); - else if (strcmp(id, "RAW6:") == 0) - sscanf(rem, "%*s%d", &s->raw6); - else if (strcmp(id, "TCP6:") == 0) - sscanf(rem, "%*s%d", &s->tcp6_hashed); - else if (strcmp(id, "FRAG:") == 0) - sscanf(rem, "%*s%d%*s%d", &s->frag4, &s->frag4_mem); - else if (strcmp(id, "FRAG6:") == 0) - sscanf(rem, "%*s%d%*s%d", &s->frag6, &s->frag6_mem); - else if (strcmp(id, "TCP:") == 0) - sscanf(rem, "%*s%d%*s%d%*s%d%*s%d%*s%d", - &s->tcp4_hashed, - &s->tcp_orphans, &s->tcp_tws, &s->tcp_total, &s->tcp_mem); -} - -int get_sockstat(struct sockstat *s) -{ - char buf[256]; - FILE *fp; - - memset(s, 0, sizeof(*s)); - - if ((fp = fdopen(net_sockstat_open(), "r")) == NULL) - return -1; - while(fgets(buf, sizeof(buf), fp) != NULL) - get_sockstat_line(buf, s); - fclose(fp); - - if ((fp = fdopen(net_sockstat6_open(), "r")) == NULL) - return 0; - while(fgets(buf, sizeof(buf), fp) != NULL) - get_sockstat_line(buf, s); - fclose(fp); - - return 0; -} - -int print_summary(void) -{ - struct sockstat s; - struct snmpstat sn; - - if (get_sockstat(&s) < 0) - perror("ss: get_sockstat"); - if (get_snmp_int("Tcp:", "CurrEstab", &sn.tcp_estab) < 0) - perror("ss: get_snmpstat"); - - printf("Total: %d (kernel %d)\n", s.socks, slabstat.socks); - - printf("TCP: %d (estab %d, closed %d, orphaned %d, synrecv %d, timewait %d/%d), ports %d\n", - s.tcp_total + slabstat.tcp_syns + s.tcp_tws, - sn.tcp_estab, - s.tcp_total - (s.tcp4_hashed+s.tcp6_hashed-s.tcp_tws), - s.tcp_orphans, - slabstat.tcp_syns, - s.tcp_tws, slabstat.tcp_tws, - slabstat.tcp_ports - ); - - printf("\n"); - printf("Transport Total IP IPv6\n"); - printf("* %-9d %-9s %-9s\n", slabstat.socks, "-", "-"); - printf("RAW %-9d %-9d %-9d\n", s.raw4+s.raw6, s.raw4, s.raw6); - printf("UDP %-9d %-9d %-9d\n", s.udp4+s.udp6, s.udp4, s.udp6); - printf("TCP %-9d %-9d %-9d\n", s.tcp4_hashed+s.tcp6_hashed, s.tcp4_hashed, s.tcp6_hashed); - printf("INET %-9d %-9d %-9d\n", - s.raw4+s.udp4+s.tcp4_hashed+ - s.raw6+s.udp6+s.tcp6_hashed, - s.raw4+s.udp4+s.tcp4_hashed, - s.raw6+s.udp6+s.tcp6_hashed); - printf("FRAG %-9d %-9d %-9d\n", s.frag4+s.frag6, s.frag4, s.frag6); - - printf("\n"); - - return 0; -} - - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) -{ - fprintf(stderr, -"Usage: ss [ OPTIONS ]\n" -" ss [ OPTIONS ] [ FILTER ]\n" -" -h, --help this message\n" -" -V, --version output version information\n" -" -n, --numeric don't resolve service names\n" -" -r, --resolve resolve host names\n" -" -a, --all display all sockets\n" -" -l, --listening display listening sockets\n" -" -o, --options show timer information\n" -" -e, --extended show detailed socket information\n" -" -m, --memory show socket memory usage\n" -" -p, --processes show process using socket\n" -" -i, --info show internal TCP information\n" -" -s, --summary show socket usage summary\n" -"\n" -" -4, --ipv4 display only IP version 4 sockets\n" -" -6, --ipv6 display only IP version 6 sockets\n" -" -0, --packet display PACKET sockets\n" -" -t, --tcp display only TCP sockets\n" -" -u, --udp display only UDP sockets\n" -" -d, --dccp display only DCCP sockets\n" -" -w, --raw display only RAW sockets\n" -" -x, --unix display only Unix domain sockets\n" -" -f, --family=FAMILY display sockets of type FAMILY\n" -"\n" -" -A, --query=QUERY\n" -" QUERY := {all|inet|tcp|udp|raw|unix|packet|netlink}[,QUERY]\n" -"\n" -" -F, --filter=FILE read filter information from FILE\n" -" FILTER := [ state TCP-STATE ] [ EXPRESSION ]\n" - ); - exit(-1); -} - - -int scan_state(const char *state) -{ - int i; - if (strcasecmp(state, "close") == 0 || - strcasecmp(state, "closed") == 0) - return (1<<SS_CLOSE); - if (strcasecmp(state, "syn-rcv") == 0) - return (1<<SS_SYN_RECV); - if (strcasecmp(state, "established") == 0) - return (1<<SS_ESTABLISHED); - if (strcasecmp(state, "all") == 0) - return SS_ALL; - if (strcasecmp(state, "connected") == 0) - return SS_ALL & ~((1<<SS_CLOSE)|(1<<SS_LISTEN)); - if (strcasecmp(state, "synchronized") == 0) - return SS_ALL & ~((1<<SS_CLOSE)|(1<<SS_LISTEN)|(1<<SS_SYN_SENT)); - if (strcasecmp(state, "bucket") == 0) - return (1<<SS_SYN_RECV)|(1<<SS_TIME_WAIT); - if (strcasecmp(state, "big") == 0) - return SS_ALL & ~((1<<SS_SYN_RECV)|(1<<SS_TIME_WAIT)); - for (i=0; i<SS_MAX; i++) { - if (strcasecmp(state, sstate_namel[i]) == 0) - return (1<<i); - } - return 0; -} - -static const struct option long_opts[] = { - { "numeric", 0, 0, 'n' }, - { "resolve", 0, 0, 'r' }, - { "options", 0, 0, 'o' }, - { "extended", 0, 0, 'e' }, - { "memory", 0, 0, 'm' }, - { "info", 0, 0, 'i' }, - { "processes", 0, 0, 'p' }, - { "dccp", 0, 0, 'd' }, - { "tcp", 0, 0, 't' }, - { "udp", 0, 0, 'u' }, - { "raw", 0, 0, 'w' }, - { "unix", 0, 0, 'x' }, - { "all", 0, 0, 'a' }, - { "listening", 0, 0, 'l' }, - { "ipv4", 0, 0, '4' }, - { "ipv6", 0, 0, '6' }, - { "packet", 0, 0, '0' }, - { "family", 1, 0, 'f' }, - { "socket", 1, 0, 'A' }, - { "summary", 0, 0, 's' }, - { "diag", 0, 0, 'D' }, - { "filter", 1, 0, 'F' }, - { "version", 0, 0, 'V' }, - { "help", 0, 0, 'h' }, - { 0 } - -}; - -int main(int argc, char *argv[]) -{ - int do_default = 1; - int saw_states = 0; - int saw_query = 0; - int do_summary = 0; - const char *dump_tcpdiag = NULL; - FILE *filter_fp = NULL; - int ch; - - memset(¤t_filter, 0, sizeof(current_filter)); - - current_filter.states = default_filter.states; - - while ((ch = getopt_long(argc, argv, "dhaletuwxnro460spf:miA:D:F:vV", - long_opts, NULL)) != EOF) { - switch(ch) { - case 'n': - resolve_services = 0; - break; - case 'r': - resolve_hosts = 1; - break; - case 'o': - show_options = 1; - break; - case 'e': - show_options = 1; - show_details++; - break; - case 'm': - show_mem = 1; - break; - case 'i': - show_tcpinfo = 1; - break; - case 'p': - show_users++; - break; - case 'd': - current_filter.dbs |= (1<<DCCP_DB); - do_default = 0; - break; - case 't': - current_filter.dbs |= (1<<TCP_DB); - do_default = 0; - break; - case 'u': - current_filter.dbs |= (1<<UDP_DB); - do_default = 0; - break; - case 'w': - current_filter.dbs |= (1<<RAW_DB); - do_default = 0; - break; - case 'x': - current_filter.dbs |= UNIX_DBM; - do_default = 0; - break; - case 'a': - current_filter.states = SS_ALL; - break; - case 'l': - current_filter.states = (1<<SS_LISTEN); - break; - case '4': - preferred_family = AF_INET; - break; - case '6': - preferred_family = AF_INET6; - break; - case '0': - preferred_family = AF_PACKET; - break; - case 'f': - if (strcmp(optarg, "inet") == 0) - preferred_family = AF_INET; - else if (strcmp(optarg, "inet6") == 0) - preferred_family = AF_INET6; - else if (strcmp(optarg, "link") == 0) - preferred_family = AF_PACKET; - else if (strcmp(optarg, "unix") == 0) - preferred_family = AF_UNIX; - else if (strcmp(optarg, "netlink") == 0) - preferred_family = AF_NETLINK; - else if (strcmp(optarg, "help") == 0) - usage(); - else { - fprintf(stderr, "ss: \"%s\" is invalid family\n", optarg); - usage(); - } - break; - case 'A': - { - char *p, *p1; - if (!saw_query) { - current_filter.dbs = 0; - saw_query = 1; - do_default = 0; - } - p = p1 = optarg; - do { - if ((p1 = strchr(p, ',')) != NULL) - *p1 = 0; - if (strcmp(p, "all") == 0) { - current_filter.dbs = ALL_DB; - } else if (strcmp(p, "inet") == 0) { - current_filter.dbs |= (1<<TCP_DB)|(1<<DCCP_DB)|(1<<UDP_DB)|(1<<RAW_DB); - } else if (strcmp(p, "udp") == 0) { - current_filter.dbs |= (1<<UDP_DB); - } else if (strcmp(p, "dccp") == 0) { - current_filter.dbs |= (1<<DCCP_DB); - } else if (strcmp(p, "tcp") == 0) { - current_filter.dbs |= (1<<TCP_DB); - } else if (strcmp(p, "raw") == 0) { - current_filter.dbs |= (1<<RAW_DB); - } else if (strcmp(p, "unix") == 0) { - current_filter.dbs |= UNIX_DBM; - } else if (strcasecmp(p, "unix_stream") == 0 || - strcmp(p, "u_str") == 0) { - current_filter.dbs |= (1<<UNIX_ST_DB); - } else if (strcasecmp(p, "unix_dgram") == 0 || - strcmp(p, "u_dgr") == 0) { - current_filter.dbs |= (1<<UNIX_DG_DB); - } else if (strcmp(p, "packet") == 0) { - current_filter.dbs |= PACKET_DBM; - } else if (strcmp(p, "packet_raw") == 0 || - strcmp(p, "p_raw") == 0) { - current_filter.dbs |= (1<<PACKET_R_DB); - } else if (strcmp(p, "packet_dgram") == 0 || - strcmp(p, "p_dgr") == 0) { - current_filter.dbs |= (1<<PACKET_DG_DB); - } else if (strcmp(p, "netlink") == 0) { - current_filter.dbs |= (1<<NETLINK_DB); - } else { - fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p); - usage(); - } - p = p1 + 1; - } while (p1); - break; - } - case 's': - do_summary = 1; - break; - case 'D': - dump_tcpdiag = optarg; - break; - case 'F': - if (filter_fp) { - fprintf(stderr, "More than one filter file\n"); - exit(-1); - } - if (optarg[0] == '-') - filter_fp = stdin; - else - filter_fp = fopen(optarg, "r"); - if (!filter_fp) { - perror("fopen filter file"); - exit(-1); - } - break; - case 'v': - case 'V': - printf("ss utility, iproute2-ss%s\n", SNAPSHOT); - exit(0); - case 'h': - case '?': - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - get_slabstat(&slabstat); - - if (do_summary) { - print_summary(); - if (do_default && argc == 0) - exit(0); - } - - if (do_default) - current_filter.dbs = default_filter.dbs; - - if (preferred_family == AF_UNSPEC) { - if (!(current_filter.dbs&~UNIX_DBM)) - preferred_family = AF_UNIX; - else if (!(current_filter.dbs&~PACKET_DBM)) - preferred_family = AF_PACKET; - else if (!(current_filter.dbs&~(1<<NETLINK_DB))) - preferred_family = AF_NETLINK; - } - - if (preferred_family != AF_UNSPEC) { - int mask2; - if (preferred_family == AF_INET || - preferred_family == AF_INET6) { - mask2= (1<<TCP_DB); - if (!do_default) - mask2 = (1<<UDP_DB)|(1<<RAW_DB); - } else if (preferred_family == AF_PACKET) { - mask2 = PACKET_DBM; - } else if (preferred_family == AF_UNIX) { - mask2 = UNIX_DBM; - } else if (preferred_family == AF_NETLINK) { - mask2 = (1<<NETLINK_DB); - } else { - mask2 = 0; - } - - if (do_default) - current_filter.dbs = mask2; - else - current_filter.dbs &= mask2; - current_filter.families = (1<<preferred_family); - } else { - if (!do_default) - current_filter.families = ~0; - else - current_filter.families = default_filter.families; - } - if (current_filter.dbs == 0) { - fprintf(stderr, "ss: no socket tables to show with such filter.\n"); - exit(0); - } - if (current_filter.families == 0) { - fprintf(stderr, "ss: no families to show with such filter.\n"); - exit(0); - } - - if (resolve_services && resolve_hosts && - (current_filter.dbs&(UNIX_DBM|(1<<TCP_DB)|(1<<UDP_DB)|(1<<DCCP_DB)))) - init_service_resolver(); - - /* Now parse filter... */ - if (argc == 0 && filter_fp) { - if (ssfilter_parse(¤t_filter.f, 0, NULL, filter_fp)) - usage(); - } - - while (argc > 0) { - if (strcmp(*argv, "state") == 0) { - NEXT_ARG(); - if (!saw_states) - current_filter.states = 0; - current_filter.states |= scan_state(*argv); - saw_states = 1; - } else if (strcmp(*argv, "exclude") == 0 || - strcmp(*argv, "excl") == 0) { - NEXT_ARG(); - if (!saw_states) - current_filter.states = SS_ALL; - current_filter.states &= ~scan_state(*argv); - saw_states = 1; - } else { - if (ssfilter_parse(¤t_filter.f, argc, argv, filter_fp)) - usage(); - break; - } - argc--; argv++; - } - - if (current_filter.states == 0) { - fprintf(stderr, "ss: no socket states to show with such filter.\n"); - exit(0); - } - - if (dump_tcpdiag) { - FILE *dump_fp = stdout; - if (!(current_filter.dbs & (1<<TCP_DB))) { - fprintf(stderr, "ss: tcpdiag dump requested and no tcp in filter.\n"); - exit(0); - } - if (dump_tcpdiag[0] != '-') { - dump_fp = fopen(dump_tcpdiag, "w"); - if (!dump_tcpdiag) { - perror("fopen dump file"); - exit(-1); - } - } - tcp_show_netlink(¤t_filter, dump_fp, TCPDIAG_GETSOCK); - fflush(dump_fp); - exit(0); - } - - netid_width = 0; - if (current_filter.dbs&(current_filter.dbs-1)) - netid_width = 5; - - state_width = 0; - if (current_filter.states&(current_filter.states-1)) - state_width = 10; - - screen_width = 80; - if (isatty(STDOUT_FILENO)) { - struct winsize w; - - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) { - if (w.ws_col > 0) - screen_width = w.ws_col; - } - } - - addrp_width = screen_width; - addrp_width -= netid_width+1; - addrp_width -= state_width+1; - addrp_width -= 14; - - if (addrp_width&1) { - if (netid_width) - netid_width++; - else if (state_width) - state_width++; - } - - addrp_width /= 2; - addrp_width--; - - serv_width = resolve_services ? 7 : 5; - - if (addrp_width < 15+serv_width+1) - addrp_width = 15+serv_width+1; - - addr_width = addrp_width - serv_width - 1; - - if (netid_width) - printf("%-*s ", netid_width, "Netid"); - if (state_width) - printf("%-*s ", state_width, "State"); - printf("%-6s %-6s ", "Recv-Q", "Send-Q"); - - printf("%*s:%-*s %*s:%-*s\n", - addr_width, "Local Address", serv_width, "Port", - addr_width, "Peer Address", serv_width, "Port"); - -//printf("%08x %08x %08x\n", current_filter.dbs, current_filter.states, current_filter.families); - fflush(stdout); - - if (current_filter.dbs & (1<<NETLINK_DB)) - netlink_show(¤t_filter); - if (current_filter.dbs & PACKET_DBM) - packet_show(¤t_filter); - if (current_filter.dbs & UNIX_DBM) - unix_show(¤t_filter); - if (current_filter.dbs & (1<<RAW_DB)) - raw_show(¤t_filter); - if (current_filter.dbs & (1<<UDP_DB)) - udp_show(¤t_filter); - if (current_filter.dbs & (1<<TCP_DB)) - tcp_show(¤t_filter, TCPDIAG_GETSOCK); - if (current_filter.dbs & (1<<DCCP_DB)) - tcp_show(¤t_filter, DCCPDIAG_GETSOCK); - return 0; -} diff --git a/misc/ssfilter.h b/misc/ssfilter.h deleted file mode 100644 index 00b92e3..0000000 --- a/misc/ssfilter.h +++ /dev/null @@ -1,21 +0,0 @@ -#define SSF_DCOND 0 -#define SSF_SCOND 1 -#define SSF_OR 2 -#define SSF_AND 3 -#define SSF_NOT 4 -#define SSF_D_GE 5 -#define SSF_D_LE 6 -#define SSF_S_GE 7 -#define SSF_S_LE 8 -#define SSF_S_AUTO 9 - -struct ssfilter -{ - int type; - struct ssfilter *post; - struct ssfilter *pred; -}; - -int ssfilter_parse(struct ssfilter **f, int argc, char **argv, FILE *fp); -void *parse_hostcond(char*); - diff --git a/misc/ssfilter.y b/misc/ssfilter.y deleted file mode 100644 index 8be5368..0000000 --- a/misc/ssfilter.y +++ /dev/null @@ -1,275 +0,0 @@ -%{ - -#include <stdio.h> -#include <stdlib.h> -#include <malloc.h> -#include <string.h> -#include "ssfilter.h" - -typedef struct ssfilter * ssfilter_t; - -#define YYSTYPE ssfilter_t - -static struct ssfilter * alloc_node(int type, void *pred) -{ - struct ssfilter *n = malloc(sizeof(*n)); - if (n == NULL) - abort(); - n->type = type; - n->pred = pred; - n->post = NULL; - return n; -} - -static char **yy_argv; -static int yy_argc; -static FILE *yy_fp; -static ssfilter_t *yy_ret; - -static int yylex(void); - -static void yyerror(char *s) -{ - fprintf(stderr, "ss: bison bellows (while parsing filter): \"%s!\"", s); -} - -%} - -%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND -%left '|' -%left '&' -%nonassoc '!' - -%% -applet: null expr - { - *yy_ret = $2; - $$ = $2; - } - | null - ; -null: /* NOTHING */ { $$ = NULL; } - ; -expr: DCOND HOSTCOND - { - $$ = alloc_node(SSF_DCOND, $2); - } - | SCOND HOSTCOND - { - $$ = alloc_node(SSF_SCOND, $2); - } - | DPORT GEQ HOSTCOND - { - $$ = alloc_node(SSF_D_GE, $3); - } - | DPORT LEQ HOSTCOND - { - $$ = alloc_node(SSF_D_LE, $3); - } - | DPORT '>' HOSTCOND - { - $$ = alloc_node(SSF_NOT, alloc_node(SSF_D_LE, $3)); - } - | DPORT '<' HOSTCOND - { - $$ = alloc_node(SSF_NOT, alloc_node(SSF_D_GE, $3)); - } - | DPORT '=' HOSTCOND - { - $$ = alloc_node(SSF_DCOND, $3); - } - | DPORT NEQ HOSTCOND - { - $$ = alloc_node(SSF_NOT, alloc_node(SSF_DCOND, $3)); - } - - | SPORT GEQ HOSTCOND - { - $$ = alloc_node(SSF_S_GE, $3); - } - | SPORT LEQ HOSTCOND - { - $$ = alloc_node(SSF_S_LE, $3); - } - | SPORT '>' HOSTCOND - { - $$ = alloc_node(SSF_NOT, alloc_node(SSF_S_LE, $3)); - } - | SPORT '<' HOSTCOND - { - $$ = alloc_node(SSF_NOT, alloc_node(SSF_S_GE, $3)); - } - | SPORT '=' HOSTCOND - { - $$ = alloc_node(SSF_SCOND, $3); - } - | SPORT NEQ HOSTCOND - { - $$ = alloc_node(SSF_NOT, alloc_node(SSF_SCOND, $3)); - } - - | AUTOBOUND - { - $$ = alloc_node(SSF_S_AUTO, NULL); - } - | expr '|' expr - { - $$ = alloc_node(SSF_OR, $1); - $$->post = $3; - } - | expr expr - { - $$ = alloc_node(SSF_AND, $1); - $$->post = $2; - } - | expr '&' expr - - { - $$ = alloc_node(SSF_AND, $1); - $$->post = $3; - } - | '!' expr - { - $$ = alloc_node(SSF_NOT, $2); - } - | '(' expr ')' - { - $$ = $2; - } -; -%% - -static char *get_token_from_line(char **ptr) -{ - char *tok, *cp = *ptr; - - while (*cp == ' ' || *cp == '\t') cp++; - - if (*cp == 0) { - *ptr = cp; - return NULL; - } - - tok = cp; - - while (*cp != 0 && *cp != ' ' && *cp != '\t') { - /* Backslash escapes everything. */ - if (*cp == '\\') { - char *tp; - for (tp = cp; tp != tok; tp--) - *tp = *(tp-1); - cp++; - tok++; - if (*cp == 0) - break; - } - cp++; - } - if (*cp) - *cp++ = 0; - *ptr = cp; - return tok; -} - -int yylex(void) -{ - static char argbuf[1024]; - static char *tokptr = argbuf; - static int argc; - char *curtok; - - do { - while (*tokptr == 0) { - tokptr = NULL; - if (argc < yy_argc) { - tokptr = yy_argv[argc]; - argc++; - } else if (yy_fp) { - while (tokptr == NULL) { - if (fgets(argbuf, sizeof(argbuf)-1, yy_fp) == NULL) - return 0; - argbuf[sizeof(argbuf)-1] = 0; - if (strlen(argbuf) == sizeof(argbuf) - 1) { - fprintf(stderr, "Too long line in filter"); - exit(-1); - } - if (argbuf[strlen(argbuf)-1] == '\n') - argbuf[strlen(argbuf)-1] = 0; - if (argbuf[0] == '#' || argbuf[0] == '0') - continue; - tokptr = argbuf; - } - } else { - return 0; - } - } - } while ((curtok = get_token_from_line(&tokptr)) == NULL); - - if (strcmp(curtok, "!") == 0 || - strcmp(curtok, "not") == 0) - return '!'; - if (strcmp(curtok, "&") == 0 || - strcmp(curtok, "&&") == 0 || - strcmp(curtok, "and") == 0) - return '&'; - if (strcmp(curtok, "|") == 0 || - strcmp(curtok, "||") == 0 || - strcmp(curtok, "or") == 0) - return '|'; - if (strcmp(curtok, "(") == 0) - return '('; - if (strcmp(curtok, ")") == 0) - return ')'; - if (strcmp(curtok, "dst") == 0) - return DCOND; - if (strcmp(curtok, "src") == 0) - return SCOND; - if (strcmp(curtok, "dport") == 0) - return DPORT; - if (strcmp(curtok, "sport") == 0) - return SPORT; - if (strcmp(curtok, ">=") == 0 || - strcmp(curtok, "ge") == 0 || - strcmp(curtok, "geq") == 0) - return GEQ; - if (strcmp(curtok, "<=") == 0 || - strcmp(curtok, "le") == 0 || - strcmp(curtok, "leq") == 0) - return LEQ; - if (strcmp(curtok, "!=") == 0 || - strcmp(curtok, "ne") == 0 || - strcmp(curtok, "neq") == 0) - return NEQ; - if (strcmp(curtok, "=") == 0 || - strcmp(curtok, "==") == 0 || - strcmp(curtok, "eq") == 0) - return '='; - if (strcmp(curtok, ">") == 0 || - strcmp(curtok, "gt") == 0) - return '>'; - if (strcmp(curtok, "<") == 0 || - strcmp(curtok, "lt") == 0) - return '<'; - if (strcmp(curtok, "autobound") == 0) - return AUTOBOUND; - yylval = (void*)parse_hostcond(curtok); - if (yylval == NULL) { - fprintf(stderr, "Cannot parse dst/src address.\n"); - exit(1); - } - return HOSTCOND; -} - -int ssfilter_parse(struct ssfilter **f, int argc, char **argv, FILE *fp) -{ - yy_argc = argc; - yy_argv = argv; - yy_fp = fp; - yy_ret = f; - - if (yyparse()) { - fprintf(stderr, " Sorry.\n"); - return -1; - } - return 0; -} diff --git a/netem/Makefile b/netem/Makefile deleted file mode 100644 index 59c7e08..0000000 --- a/netem/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -DISTGEN = maketable normal pareto paretonormal -DISTDATA = normal.dist pareto.dist paretonormal.dist experimental.dist - -HOSTCC ?= $(CC) -LDLIBS += -lm - -all: $(DISTGEN) $(DISTDATA) - -$(DISTGEN): - $(HOSTCC) $(CCOPTS) -I../include -o $@ $@.c -lm - -%.dist: % - ./$* > $@ - -experimental.dist: maketable experimental.dat - ./maketable experimental.dat > experimental.dist - -install: all - mkdir -p $(DESTDIR)/usr/lib/tc - for i in $(DISTDATA); \ - do install -m 755 $$i $(DESTDIR)/usr/lib/tc; \ - done - -clean: - rm -f $(DISTDATA) $(DISTGEN) diff --git a/netem/README.distribution b/netem/README.distribution deleted file mode 100644 index 23f7ecb..0000000 --- a/netem/README.distribution +++ /dev/null @@ -1,97 +0,0 @@ -Notes about distribution tables from Nistnet -------------------------------------------------------------------------------- -I. About the distribution tables - -The table used for "synthesizing" the distribution is essentially a scaled, -translated, inverse to the cumulative distribution function. - -Here's how to think about it: Let F() be the cumulative distribution -function for a probability distribution X. We'll assume we've scaled -things so that X has mean 0 and standard deviation 1, though that's not -so important here. Then: - - F(x) = P(X <= x) = \int_{-inf}^x f - -where f is the probability density function. - -F is monotonically increasing, so has an inverse function G, with range -0 to 1. Here, G(t) = the x such that P(X <= x) = t. (In general, G may -have singularities if X has point masses, i.e., points x such that -P(X = x) > 0.) - -Now we create a tabular representation of G as follows: Choose some table -size N, and for the ith entry, put in G(i/N). Let's call this table T. - -The claim now is, I can create a (discrete) random variable Y whose -distribution has the same approximate "shape" as X, simply by letting -Y = T(U), where U is a discrete uniform random variable with range 1 to N. -To see this, it's enough to show that Y's cumulative distribution function, -(let's call it H), is a discrete approximation to F. But - - H(x) = P(Y <= x) - = (# of entries in T <= x) / N -- as Y chosen uniformly from T - = i/N, where i is the largest integer such that G(i/N) <= x - = i/N, where i is the largest integer such that i/N <= F(x) - -- since G and F are inverse functions (and F is - increasing) - = floor(N*F(x))/N - -as desired. - -II. How to create distribution tables (in theory) - -How can we create this table in practice? In some cases, F may have a -simple expression which allows evaluating its inverse directly. The -pareto distribution is one example of this. In other cases, and -especially for matching an experimentally observed distribution, it's -easiest simply to create a table for F and "invert" it. Here, we give -a concrete example, namely how the new "experimental" distribution was -created. - -1. Collect enough data points to characterize the distribution. Here, I -collected 25,000 "ping" roundtrip times to a "distant" point (time.nist.gov). -That's far more data than is really necessary, but it was fairly painless to -collect it, so... - -2. Normalize the data so that it has mean 0 and standard deviation 1. - -3. Determine the cumulative distribution. The code I wrote creates a table -covering the range -10 to +10, with granularity .00005. Obviously, this -is absurdly over-precise, but since it's a one-time only computation, I -figured it hardly mattered. - -4. Invert the table: for each table entry F(x) = y, make the y*TABLESIZE -(here, 4096) entry be x*TABLEFACTOR (here, 8192). This creates a table -for the ("normalized") inverse of size TABLESIZE, covering its domain 0 -to 1 with granularity 1/TABLESIZE. Note that even with the granularity -used in creating the table for F, it's possible not all the entries in -the table for G will be filled in. So, make a pass through the -inverse's table, filling in any missing entries by linear interpolation. - -III. How to create distribution tables (in practice) - -If you want to do all this yourself, I've provided several tools to help: - -1. maketable does the steps 2-4 above, and then generates the appropriate -header file. So if you have your own time distribution, you can generate -the header simply by: - - maketable < time.values > header.h - -2. As explained in the other README file, the somewhat sleazy way I have -of generating correlated values needs correction. You can generate your -own correction tables by compiling makesigtable and makemutable with -your header file. Check the Makefile to see how this is done. - -3. Warning: maketable, makesigtable and especially makemutable do -enormous amounts of floating point arithmetic. Don't try running -these on an old 486. (NIST Net itself will run fine on such a -system, since in operation, it just needs to do a few simple integral -calculations. But getting there takes some work.) - -4. The tables produced are all normalized for mean 0 and standard -deviation 1. How do you know what values to use for real? Here, I've -provided a simple "stats" utility. Give it a series of floating point -values, and it will return their mean (mu), standard deviation (sigma), -and correlation coefficient (rho). You can then plug these values -directly into NIST Net. diff --git a/netem/experimental.dat b/netem/experimental.dat deleted file mode 100644 index 3663a3e..0000000 --- a/netem/experimental.dat +++ /dev/null @@ -1,13448 +0,0 @@ -211.6 -205.6 -203.0 -218.6 -213.9 -199.1 -208.7 -207.7 -203.4 -201.7 -200.3 -213.8 -213.4 -209.8 -204.3 -201.8 -196.3 -216.2 -208.9 -202.4 -205.2 -211.1 -210.9 -208.5 -199.9 -211.6 -211.9 -204.6 -215.4 -202.5 -206.5 -201.1 -198.4 -220.2 -203.7 -219.5 -199.1 -207.6 -205.3 -202.3 -219.7 -230.0 -211.0 -202.7 -209.9 -215.4 -202.9 -209.6 -200.5 -197.3 -212.3 -207.6 -210.5 -202.7 -205.7 -211.2 -208.0 -211.0 -209.4 -204.8 -204.8 -208.7 -210.1 -205.3 -202.5 -210.4 -209.4 -204.5 -204.7 -215.0 -202.6 -209.9 -220.2 -203.8 -206.3 -199.4 -221.8 -200.0 -199.6 -209.3 -206.2 -215.8 -196.9 -211.6 -198.4 -201.2 -209.4 -204.3 -219.0 -212.7 -214.6 -196.3 -202.0 -201.9 -197.5 -229.5 -207.5 -213.8 -209.2 -212.9 -193.9 -200.8 -208.6 -196.8 -201.3 -204.9 -204.7 -209.5 -211.3 -215.3 -203.7 -190.1 -235.6 -203.8 -210.0 -209.7 -214.3 -213.0 -206.3 -197.7 -208.2 -226.3 -216.5 -198.0 -201.3 -211.3 -195.8 -210.9 -208.1 -201.2 -201.7 -213.1 -207.9 -206.6 -207.1 -202.2 -199.6 -205.5 -207.3 -219.7 -204.1 -204.4 -209.0 -212.7 -196.4 -214.0 -208.8 -209.7 -217.2 -196.2 -195.0 -227.7 -207.2 -233.3 -207.9 -204.0 -194.4 -219.2 -208.7 -198.6 -205.0 -204.0 -223.7 -207.4 -209.2 -208.7 -205.4 -212.8 -207.8 -203.0 -204.1 -221.0 -198.4 -217.7 -218.4 -374.2 -220.1 -210.8 -212.1 -214.3 -213.3 -210.3 -202.4 -209.7 -218.1 -205.0 -204.5 -220.3 -209.8 -218.3 -216.6 -206.0 -208.9 -221.0 -213.0 -202.1 -204.2 -220.6 -212.4 -226.1 -208.8 -206.1 -220.7 -219.3 -210.9 -211.2 -213.0 -201.4 -210.5 -206.2 -201.9 -224.5 -219.3 -201.1 -195.6 -223.6 -196.7 -213.7 -202.3 -215.6 -211.4 -209.6 -207.6 -212.4 -203.4 -205.4 -216.1 -216.7 -205.3 -213.9 -208.9 -208.4 -205.1 -199.3 -200.6 -199.1 -203.2 -207.6 -203.8 -201.9 -208.5 -196.4 -213.6 -217.6 -201.5 -210.1 -213.5 -203.8 -214.1 -211.9 -201.5 -186.9 -199.7 -209.1 -200.2 -205.8 -206.7 -200.0 -198.1 -209.3 -207.8 -208.7 -208.0 -208.6 -231.3 -214.5 -210.1 -200.8 -208.9 -216.9 -205.7 -214.9 -236.8 -200.9 -219.1 -204.6 -210.0 -214.0 -222.6 -209.6 -207.0 -196.3 -207.7 -207.9 -208.0 -220.2 -198.2 -204.9 -204.1 -201.0 -204.8 -213.3 -203.9 -222.5 -205.2 -203.5 -209.7 -212.1 -210.1 -221.1 -210.2 -208.0 -201.4 -209.0 -211.9 -201.6 -214.4 -199.6 -198.8 -210.2 -207.3 -206.5 -204.8 -196.3 -199.8 -206.4 -195.3 -202.8 -202.7 -203.8 -211.2 -208.4 -198.6 -202.0 -214.9 -204.2 -201.1 -195.9 -196.1 -211.2 -197.0 -207.7 -196.6 -205.7 -211.4 -201.4 -205.0 -195.5 -198.9 -214.4 -207.3 -204.2 -207.2 -198.5 -220.7 -214.1 -213.2 -207.7 -203.6 -265.8 -221.0 -213.1 -195.4 -197.3 -213.0 -207.7 -206.0 -198.4 -202.3 -213.9 -218.6 -207.6 -206.1 -212.8 -216.8 -213.7 -209.8 -198.1 -202.4 -205.3 -207.0 -209.2 -209.9 -204.4 -199.6 -205.5 -203.9 -216.0 -213.1 -202.4 -199.0 -219.5 -193.9 -197.3 -212.2 -216.7 -217.5 -201.0 -206.2 -202.9 -211.3 -203.1 -218.0 -208.6 -217.8 -209.0 -211.8 -220.1 -212.7 -207.2 -221.2 -215.2 -196.9 -216.6 -203.1 -207.1 -216.7 -206.7 -215.0 -219.3 -204.3 -219.6 -207.1 -211.8 -210.2 -217.2 -207.9 -219.9 -205.4 -201.1 -214.1 -205.8 -212.5 -222.8 -211.9 -217.4 -203.8 -222.9 -206.6 -207.6 -197.5 -206.2 -218.5 -220.3 -207.7 -203.5 -226.4 -216.8 -206.0 -193.2 -198.2 -201.3 -202.4 -208.5 -212.6 -205.0 -202.2 -210.0 -202.4 -203.9 -193.3 -212.4 -203.4 -212.1 -206.1 -206.9 -207.0 -216.1 -201.1 -204.7 -202.4 -207.5 -203.9 -200.9 -210.0 -207.1 -217.2 -197.4 -199.2 -210.8 -209.2 -218.4 -200.2 -211.7 -213.6 -203.3 -197.9 -203.0 -204.2 -207.9 -209.4 -225.4 -237.3 -209.5 -208.2 -207.5 -207.0 -203.0 -219.3 -228.3 -213.5 -205.1 -198.9 -212.7 -201.5 -210.0 -206.5 -203.3 -206.1 -210.1 -219.7 -206.8 -215.4 -220.4 -217.3 -211.4 -206.0 -208.3 -207.3 -205.5 -210.8 -209.3 -197.2 -207.2 -191.7 -204.2 -207.2 -216.1 -209.1 -203.8 -201.8 -208.7 -212.4 -214.5 -213.8 -201.3 -219.7 -214.8 -211.9 -223.8 -208.6 -203.5 -207.4 -207.0 -198.0 -208.2 -218.6 -205.1 -214.6 -215.2 -215.3 -204.3 -210.1 -221.9 -210.7 -198.2 -205.2 -201.1 -219.0 -207.2 -205.9 -203.8 -200.5 -217.5 -208.7 -208.4 -192.6 -211.0 -209.1 -206.5 -197.4 -202.1 -210.0 -198.3 -222.2 -211.9 -212.3 -222.2 -195.1 -200.7 -212.1 -208.3 -211.8 -211.7 -206.5 -211.8 -207.6 -214.2 -207.7 -204.7 -208.2 -208.4 -207.9 -212.1 -223.2 -206.3 -205.6 -201.8 -211.9 -207.6 -203.0 -221.2 -206.3 -222.4 -253.5 -204.4 -218.9 -211.9 -210.9 -214.0 -226.7 -214.4 -199.7 -213.8 -207.0 -201.8 -206.6 -203.1 -202.1 -203.6 -213.9 -196.9 -200.4 -204.6 -333.4 -204.5 -220.9 -207.3 -212.1 -203.7 -200.9 -198.2 -204.0 -201.4 -198.2 -209.6 -211.5 -201.2 -200.4 -207.4 -200.7 -213.8 -207.7 -188.0 -210.0 -210.5 -207.3 -198.6 -206.1 -186.9 -201.4 -204.0 -200.8 -207.8 -211.7 -198.7 -206.1 -213.0 -214.8 -212.8 -208.8 -210.4 -206.5 -210.1 -201.7 -202.7 -201.3 -194.1 -200.8 -196.8 -204.2 -217.5 -209.0 -198.7 -203.2 -213.8 -198.0 -207.1 -204.0 -215.3 -199.5 -214.1 -200.1 -206.9 -219.9 -204.8 -208.6 -207.8 -207.5 -203.8 -210.9 -210.6 -205.3 -202.1 -212.9 -214.8 -210.9 -217.2 -218.3 -221.5 -201.8 -212.7 -215.0 -206.7 -222.8 -210.9 -211.5 -202.0 -208.1 -268.9 -205.8 -204.0 -198.4 -206.3 -209.3 -206.4 -207.4 -226.9 -209.9 -199.6 -206.5 -210.9 -224.1 -211.9 -214.4 -212.2 -211.5 -209.4 -205.3 -204.8 -207.7 -208.9 -213.7 -201.0 -217.4 -198.1 -219.0 -206.5 -229.1 -220.1 -196.8 -203.1 -208.8 -201.7 -195.7 -207.0 -202.4 -206.6 -204.9 -196.6 -204.3 -198.6 -203.9 -215.8 -194.9 -202.7 -225.5 -205.9 -201.4 -213.1 -214.2 -218.8 -209.4 -204.4 -206.7 -209.8 -198.4 -211.8 -212.1 -209.1 -202.3 -213.7 -215.5 -218.3 -209.1 -216.6 -214.8 -206.4 -205.6 -214.4 -209.2 -211.7 -211.3 -211.0 -205.6 -204.2 -191.7 -213.8 -204.9 -205.3 -212.0 -199.9 -198.3 -211.8 -203.0 -212.2 -203.0 -201.8 -214.4 -214.1 -199.6 -205.3 -208.2 -196.7 -196.7 -209.1 -205.1 -212.5 -213.1 -197.3 -208.8 -218.0 -220.0 -198.4 -206.3 -206.9 -253.2 -194.3 -202.6 -210.6 -219.1 -197.8 -197.1 -194.0 -211.6 -209.6 -198.3 -213.0 -207.7 -207.0 -213.3 -206.9 -197.6 -204.8 -202.0 -200.0 -215.2 -204.5 -206.3 -206.7 -203.2 -194.9 -206.3 -209.9 -210.6 -214.2 -208.6 -207.4 -213.9 -210.4 -210.0 -200.6 -203.8 -202.7 -204.2 -202.7 -210.2 -192.5 -215.4 -211.7 -208.3 -204.8 -203.3 -197.7 -216.7 -200.9 -203.6 -208.6 -206.5 -209.9 -200.1 -198.4 -203.3 -210.4 -211.6 -202.0 -203.1 -204.0 -204.0 -215.0 -211.4 -202.0 -197.2 -197.6 -209.9 -205.4 -213.1 -199.1 -212.4 -216.1 -218.3 -214.6 -224.1 -206.9 -199.4 -213.4 -261.2 -199.4 -208.8 -209.9 -205.7 -203.1 -203.2 -204.6 -201.6 -210.6 -213.2 -214.8 -203.8 -204.9 -220.7 -201.5 -212.5 -216.8 -209.7 -203.1 -213.3 -204.7 -218.2 -215.5 -215.6 -211.6 -214.2 -205.1 -216.6 -216.3 -203.5 -200.8 -213.7 -221.9 -215.0 -210.2 -217.1 -214.7 -208.8 -217.4 -231.1 -213.7 -215.0 -213.5 -216.7 -207.7 -201.0 -210.4 -210.9 -206.7 -203.7 -199.2 -209.3 -206.3 -202.4 -210.1 -212.3 -202.2 -207.2 -197.8 -205.9 -202.0 -214.2 -203.5 -204.4 -200.0 -204.0 -193.8 -192.3 -229.0 -204.5 -194.8 -213.6 -215.9 -214.8 -221.6 -208.5 -201.5 -204.4 -206.4 -194.5 -199.4 -201.5 -209.7 -212.5 -202.1 -208.2 -205.4 -204.5 -199.4 -194.5 -199.6 -201.5 -206.2 -219.9 -198.5 -216.2 -195.7 -205.0 -208.0 -204.9 -195.9 -207.4 -216.9 -195.9 -204.4 -208.3 -206.1 -188.5 -202.3 -201.7 -200.5 -206.2 -191.5 -218.6 -206.5 -208.9 -209.9 -201.5 -212.7 -203.2 -209.7 -212.1 -208.4 -207.2 -206.5 -204.5 -222.7 -207.6 -207.4 -210.3 -212.2 -219.1 -215.2 -211.1 -205.9 -205.5 -205.9 -203.1 -205.4 -184.5 -205.0 -194.8 -213.5 -209.8 -195.4 -202.9 -205.3 -196.3 -202.0 -198.2 -201.5 -195.3 -230.9 -207.8 -212.6 -202.7 -204.8 -205.0 -202.8 -206.2 -200.2 -202.7 -203.5 -205.5 -196.9 -209.4 -212.1 -200.8 -205.0 -208.0 -207.1 -198.0 -204.8 -205.8 -200.9 -202.1 -202.4 -206.9 -209.1 -199.7 -197.1 -206.9 -200.2 -193.7 -195.0 -250.8 -207.5 -204.5 -208.8 -209.8 -194.8 -200.2 -205.1 -197.3 -208.3 -200.4 -204.7 -211.1 -203.4 -218.2 -194.6 -201.5 -202.2 -202.9 -198.8 -218.2 -201.7 -189.8 -210.1 -208.0 -204.3 -205.8 -204.2 -207.8 -200.2 -197.9 -198.9 -208.1 -202.4 -196.2 -195.5 -204.6 -211.0 -205.0 -193.6 -197.2 -198.6 -193.8 -198.9 -232.4 -201.8 -212.2 -208.6 -204.5 -199.3 -211.2 -203.1 -209.7 -214.3 -203.9 -200.3 -203.3 -206.1 -206.9 -209.1 -209.1 -199.3 -199.4 -198.8 -198.9 -199.9 -193.7 -204.6 -203.4 -199.7 -212.6 -200.7 -208.1 -198.8 -200.5 -209.2 -208.4 -205.7 -197.1 -202.6 -199.5 -208.4 -200.1 -204.9 -202.9 -201.5 -207.6 -200.6 -204.2 -210.0 -207.1 -205.1 -198.5 -204.9 -196.5 -208.0 -202.4 -202.7 -196.2 -206.9 -201.5 -203.3 -198.7 -211.9 -208.4 -206.7 -209.4 -204.0 -202.3 -205.0 -205.3 -206.0 -213.1 -205.7 -199.3 -206.2 -204.6 -209.3 -205.7 -202.7 -213.3 -202.3 -197.8 -196.5 -193.4 -211.6 -209.9 -195.5 -196.2 -210.2 -207.1 -207.0 -221.8 -217.2 -215.4 -207.0 -200.1 -207.5 -206.0 -200.7 -190.9 -209.8 -213.5 -206.3 -196.0 -213.1 -202.7 -211.6 -196.5 -209.9 -212.3 -199.9 -206.8 -225.1 -203.9 -204.3 -197.7 -203.5 -203.2 -193.5 -200.9 -201.4 -189.1 -203.9 -194.5 -205.4 -204.8 -204.9 -201.3 -208.4 -196.9 -206.8 -207.7 -201.6 -210.3 -211.6 -209.8 -200.2 -205.2 -197.6 -195.9 -212.8 -206.4 -201.0 -208.2 -207.5 -202.5 -193.3 -206.5 -221.2 -198.8 -216.6 -217.0 -209.1 -206.6 -197.7 -211.0 -199.9 -198.0 -210.4 -200.5 -211.7 -219.6 -206.8 -207.2 -210.6 -205.4 -203.8 -207.4 -206.2 -205.1 -208.7 -196.3 -204.7 -210.8 -214.4 -196.3 -206.5 -210.8 -193.2 -203.3 -203.9 -207.7 -194.9 -203.7 -195.5 -218.7 -201.1 -199.5 -207.6 -209.3 -207.5 -205.7 -203.9 -205.4 -201.3 -205.8 -205.4 -208.8 -214.3 -203.4 -207.5 -188.9 -205.5 -200.7 -212.5 -197.9 -219.0 -213.6 -197.3 -202.7 -216.3 -205.0 -210.2 -203.2 -203.9 -206.8 -213.6 -200.1 -204.4 -211.4 -213.4 -200.2 -208.4 -209.1 -198.8 -207.4 -195.0 -205.6 -200.5 -204.3 -201.9 -206.4 -199.0 -196.1 -207.6 -195.4 -197.2 -200.7 -190.8 -211.9 -191.5 -201.4 -193.5 -205.1 -206.8 -199.5 -207.4 -209.8 -199.1 -194.6 -201.6 -211.6 -206.8 -203.9 -196.8 -206.3 -210.1 -200.6 -227.4 -201.9 -210.8 -205.8 -217.2 -205.8 -196.1 -200.7 -213.8 -205.4 -211.6 -212.3 -213.6 -201.7 -199.9 -203.2 -212.6 -211.0 -208.1 -198.1 -201.7 -211.6 -207.4 -212.4 -207.3 -214.9 -214.5 -214.5 -202.7 -200.1 -206.4 -213.4 -189.7 -203.4 -202.2 -198.2 -206.5 -213.7 -207.6 -202.8 -209.2 -205.5 -196.4 -207.6 -207.4 -207.3 -188.8 -215.6 -195.4 -207.7 -208.2 -200.9 -208.4 -203.3 -210.8 -199.6 -208.3 -206.7 -201.6 -202.9 -197.5 -206.4 -209.0 -208.4 -211.6 -204.4 -210.0 -190.9 -199.3 -207.6 -202.5 -197.0 -200.8 -203.1 -204.0 -199.0 -208.0 -204.6 -196.6 -200.8 -205.2 -198.8 -203.0 -208.3 -200.1 -205.5 -203.7 -202.2 -203.8 -211.5 -201.8 -213.2 -207.4 -207.8 -202.2 -208.2 -204.2 -200.4 -186.1 -188.5 -220.4 -212.8 -193.3 -196.9 -203.0 -207.3 -202.4 -201.7 -204.8 -192.2 -218.7 -226.3 -209.5 -201.4 -207.3 -202.6 -210.7 -208.4 -208.4 -207.4 -210.4 -191.2 -203.6 -197.1 -207.5 -197.8 -206.2 -214.5 -208.2 -207.3 -204.7 -199.6 -206.3 -189.0 -214.4 -209.4 -208.1 -199.9 -190.5 -223.0 -198.8 -201.1 -192.4 -204.0 -209.0 -206.7 -204.3 -198.7 -210.9 -212.0 -204.8 -204.2 -199.5 -203.5 -203.0 -190.6 -207.9 -207.9 -193.2 -210.9 -200.1 -207.6 -193.6 -204.9 -197.7 -200.9 -213.0 -215.0 -204.4 -196.6 -209.6 -209.9 -199.8 -198.8 -202.1 -203.4 -205.4 -204.4 -196.2 -190.7 -210.9 -197.7 -194.7 -204.0 -201.5 -195.3 -209.0 -203.6 -196.1 -205.2 -206.7 -206.6 -191.4 -193.4 -206.6 -205.9 -207.9 -201.7 -213.3 -199.4 -202.8 -196.1 -208.3 -206.4 -205.2 -191.9 -207.3 -191.5 -210.8 -200.9 -210.4 -208.3 -211.0 -202.7 -198.8 -196.8 -202.7 -196.9 -214.6 -210.2 -226.1 -220.8 -213.5 -194.9 -210.4 -203.7 -203.7 -180.8 -213.7 -208.0 -209.8 -209.7 -213.8 -185.5 -208.5 -203.5 -212.8 -193.1 -199.2 -211.0 -217.4 -211.0 -202.7 -205.0 -208.6 -197.5 -197.1 -201.0 -195.9 -208.4 -205.7 -205.8 -194.0 -204.4 -194.5 -194.3 -200.1 -209.5 -218.0 -202.8 -197.5 -206.7 -199.8 -205.2 -201.4 -205.2 -186.0 -208.4 -218.4 -206.7 -201.9 -209.7 -208.0 -203.9 -193.1 -202.0 -198.0 -199.5 -211.0 -191.8 -198.7 -197.3 -195.6 -202.9 -203.4 -206.1 -205.6 -207.5 -220.8 -204.7 -207.7 -252.5 -203.9 -203.2 -201.3 -200.1 -201.1 -196.8 -197.6 -206.4 -209.6 -197.9 -199.4 -212.6 -205.4 -200.9 -197.5 -202.2 -199.5 -206.7 -215.1 -216.4 -221.9 -199.2 -246.4 -196.0 -205.1 -205.4 -207.8 -192.6 -204.6 -209.2 -213.4 -198.9 -205.3 -205.8 -201.1 -195.2 -199.4 -200.8 -210.5 -202.3 -217.9 -208.4 -220.8 -218.4 -195.7 -199.4 -198.8 -192.0 -210.9 -218.5 -194.5 -203.6 -195.0 -208.8 -197.4 -204.1 -200.7 -201.0 -206.6 -202.2 -208.7 -213.1 -198.3 -212.2 -201.9 -206.3 -203.4 -198.0 -198.0 -205.3 -199.6 -196.6 -202.8 -201.7 -208.7 -195.6 -199.4 -205.4 -205.2 -202.2 -193.3 -191.9 -195.1 -201.1 -210.5 -208.7 -196.9 -193.4 -200.8 -199.6 -204.1 -200.4 -197.6 -204.1 -206.9 -205.2 -206.9 -194.7 -200.4 -198.8 -201.7 -201.8 -207.0 -193.2 -199.9 -201.3 -192.5 -197.9 -206.9 -190.0 -203.8 -208.8 -200.9 -203.3 -194.5 -192.6 -204.9 -205.5 -196.6 -194.8 -197.9 -198.1 -211.2 -198.8 -202.2 -205.9 -199.5 -204.7 -201.6 -201.2 -203.4 -204.2 -190.7 -206.7 -205.4 -208.4 -203.1 -204.2 -198.4 -194.3 -191.6 -198.9 -203.5 -198.7 -192.2 -198.4 -194.5 -181.1 -200.9 -200.0 -209.2 -210.4 -200.0 -201.1 -193.9 -207.0 -193.4 -202.6 -192.8 -196.0 -203.8 -184.2 -179.3 -202.3 -191.4 -199.7 -195.4 -189.9 -197.0 -187.5 -192.1 -198.3 -202.2 -205.0 -212.3 -198.0 -205.5 -210.1 -197.6 -198.7 -206.6 -203.4 -194.3 -181.2 -199.0 -202.4 -189.1 -181.6 -200.4 -188.1 -180.1 -203.1 -201.1 -195.5 -201.6 -201.3 -197.6 -196.0 -205.5 -184.9 -186.5 -190.8 -188.6 -207.2 -199.5 -198.6 -199.8 -212.2 -208.1 -196.9 -199.6 -205.3 -196.9 -188.9 -205.4 -212.5 -197.5 -201.8 -188.8 -187.1 -199.9 -195.4 -188.7 -198.7 -185.0 -191.6 -193.3 -191.8 -209.4 -197.4 -195.2 -189.4 -189.7 -199.9 -199.3 -188.7 -188.3 -190.9 -181.6 -209.8 -194.6 -198.2 -199.9 -198.1 -186.8 -195.3 -190.9 -198.8 -189.3 -207.5 -179.2 -188.8 -185.6 -206.2 -184.8 -190.7 -203.5 -199.2 -202.0 -197.6 -197.2 -196.4 -210.4 -200.1 -194.8 -186.7 -198.2 -197.8 -186.5 -200.2 -192.7 -192.7 -190.4 -220.9 -207.5 -188.6 -198.5 -203.0 -202.2 -189.6 -177.3 -194.8 -195.2 -243.9 -196.5 -180.6 -214.6 -196.4 -220.6 -194.7 -200.5 -193.7 -199.7 -203.0 -201.4 -187.7 -199.8 -191.8 -203.9 -203.8 -191.3 -206.6 -201.7 -202.1 -202.6 -200.0 -203.6 -195.9 -204.8 -212.8 -199.2 -203.3 -206.6 -192.2 -205.0 -198.9 -205.3 -195.0 -198.1 -190.4 -203.7 -188.2 -204.2 -211.1 -192.5 -194.5 -198.3 -205.7 -198.5 -210.2 -206.8 -195.4 -200.8 -202.7 -220.0 -204.1 -209.5 -200.2 -187.1 -205.4 -202.6 -203.3 -214.1 -193.8 -207.4 -208.2 -204.9 -215.9 -202.6 -198.0 -193.8 -198.2 -206.2 -203.9 -190.6 -210.8 -195.6 -207.6 -206.6 -195.4 -189.9 -199.7 -203.1 -207.1 -192.2 -197.3 -197.6 -193.3 -207.9 -201.3 -206.8 -201.9 -195.7 -204.1 -201.1 -192.5 -206.7 -213.1 -195.2 -205.1 -196.2 -203.5 -195.5 -200.3 -194.7 -194.5 -200.6 -211.2 -202.1 -194.6 -199.9 -212.6 -206.8 -196.2 -205.8 -202.8 -201.6 -205.2 -205.8 -193.1 -202.0 -196.2 -208.1 -209.5 -199.8 -208.8 -192.3 -207.9 -201.3 -205.7 -205.9 -208.6 -210.3 -202.2 -212.1 -210.3 -199.6 -200.8 -209.1 -202.5 -215.0 -201.5 -209.2 -207.0 -215.3 -205.6 -213.7 -203.7 -199.8 -201.4 -194.7 -194.3 -188.7 -200.9 -203.8 -203.2 -212.5 -207.0 -211.3 -204.3 -204.5 -194.0 -210.7 -207.1 -207.5 -200.7 -200.8 -200.7 -200.1 -203.7 -191.1 -201.8 -194.8 -195.2 -197.4 -190.5 -192.7 -206.6 -200.8 -204.3 -206.5 -209.8 -202.5 -207.6 -198.4 -203.3 -202.1 -200.6 -198.4 -191.0 -203.5 -198.6 -184.3 -183.7 -189.1 -205.4 -187.8 -194.5 -199.2 -196.4 -210.9 -176.8 -191.6 -182.7 -181.3 -205.7 -203.2 -186.3 -187.6 -189.1 -180.8 -180.2 -187.6 -194.9 -192.8 -185.2 -198.3 -209.3 -177.5 -193.9 -193.1 -203.4 -192.1 -200.9 -182.6 -204.9 -197.6 -212.8 -206.9 -193.3 -201.0 -195.3 -197.1 -189.6 -198.5 -190.4 -188.8 -197.7 -189.9 -200.7 -196.8 -186.3 -181.5 -184.9 -200.2 -198.7 -205.8 -200.2 -198.3 -207.9 -206.1 -201.5 -197.8 -199.5 -198.1 -211.3 -201.6 -202.4 -196.0 -197.7 -209.2 -199.3 -205.5 -191.6 -206.4 -196.5 -209.5 -203.4 -201.4 -200.1 -205.2 -190.9 -205.1 -197.5 -196.1 -194.4 -194.7 -188.9 -180.8 -206.5 -199.8 -193.1 -195.2 -192.7 -199.2 -199.5 -188.1 -180.2 -191.0 -206.9 -208.2 -202.5 -200.0 -207.0 -201.6 -195.6 -195.6 -195.0 -196.3 -190.2 -194.0 -182.9 -192.1 -206.5 -181.4 -192.3 -199.6 -201.6 -192.4 -200.5 -207.1 -198.5 -198.8 -190.8 -200.3 -199.3 -200.5 -187.7 -208.3 -205.6 -189.3 -198.4 -204.9 -197.4 -198.7 -190.6 -214.5 -212.5 -207.6 -196.9 -183.4 -185.1 -205.8 -226.5 -202.5 -201.8 -202.9 -210.4 -189.7 -195.6 -198.7 -193.0 -198.8 -193.1 -202.5 -195.2 -195.0 -198.3 -203.6 -208.3 -195.9 -200.8 -189.4 -207.9 -182.8 -194.9 -199.7 -180.7 -187.2 -189.5 -196.1 -190.1 -192.5 -185.7 -212.2 -204.2 -191.9 -184.5 -182.5 -198.5 -191.0 -192.0 -195.6 -201.1 -193.7 -203.8 -200.5 -199.1 -190.3 -209.5 -195.0 -184.0 -193.6 -203.3 -191.4 -194.9 -195.5 -193.5 -182.7 -189.7 -196.1 -178.9 -199.5 -195.3 -185.9 -199.1 -210.0 -195.7 -193.8 -196.4 -195.3 -201.4 -209.5 -205.6 -197.5 -188.9 -193.8 -185.3 -193.3 -198.1 -201.4 -184.7 -182.5 -183.7 -185.5 -199.8 -200.3 -194.1 -176.9 -192.2 -200.0 -186.4 -191.6 -200.1 -202.3 -205.1 -186.4 -182.3 -194.7 -177.5 -201.4 -189.6 -195.5 -185.4 -194.8 -204.1 -188.0 -182.1 -181.7 -184.5 -234.2 -209.4 -193.3 -204.0 -184.7 -194.3 -193.4 -191.1 -188.3 -193.9 -198.2 -202.8 -198.1 -191.2 -200.9 -205.4 -203.6 -193.8 -215.8 -185.8 -195.4 -204.7 -190.3 -190.7 -177.7 -182.1 -193.2 -178.3 -199.3 -203.5 -187.3 -198.8 -187.8 -187.7 -186.7 -200.0 -190.0 -203.1 -181.7 -207.2 -183.8 -180.3 -193.5 -190.2 -193.7 -198.6 -195.6 -192.1 -200.5 -188.6 -190.9 -188.0 -192.8 -191.4 -179.9 -197.6 -200.6 -206.1 -201.3 -199.6 -198.8 -201.0 -180.2 -202.9 -197.3 -186.1 -200.5 -182.4 -192.7 -194.5 -182.8 -193.9 -195.1 -187.7 -201.0 -196.1 -194.0 -198.8 -192.8 -186.1 -200.6 -186.3 -187.6 -178.0 -175.8 -198.9 -199.3 -193.4 -193.3 -198.7 -194.5 -180.9 -197.3 -189.7 -193.0 -208.2 -200.1 -193.9 -211.2 -206.6 -210.2 -185.5 -180.8 -206.8 -185.5 -195.8 -199.3 -187.9 -194.9 -175.8 -198.1 -199.0 -200.6 -300.8 -194.0 -199.7 -181.2 -189.9 -195.3 -209.6 -198.1 -184.9 -192.5 -188.8 -193.8 -201.4 -208.2 -192.5 -199.9 -185.0 -207.5 -196.5 -198.8 -193.3 -200.1 -186.7 -194.4 -194.3 -197.2 -198.4 -192.8 -194.3 -188.6 -194.7 -190.7 -192.1 -194.5 -185.7 -194.6 -177.5 -203.6 -180.8 -185.0 -178.9 -205.7 -187.4 -185.9 -192.9 -182.7 -197.3 -198.0 -194.5 -194.7 -194.7 -198.2 -184.7 -199.0 -200.9 -195.4 -198.7 -188.1 -187.5 -190.6 -179.2 -190.2 -195.9 -188.8 -205.7 -191.9 -204.0 -193.3 -199.5 -200.7 -179.3 -190.4 -206.4 -199.8 -189.5 -194.1 -203.3 -196.9 -200.1 -179.6 -217.2 -199.0 -184.0 -177.4 -200.5 -205.3 -193.2 -198.8 -187.2 -191.2 -186.6 -188.3 -199.4 -192.8 -209.8 -181.5 -192.8 -176.0 -189.9 -203.5 -192.5 -193.1 -190.3 -193.1 -203.0 -194.6 -188.4 -199.8 -199.6 -195.0 -200.3 -195.5 -198.5 -203.1 -193.4 -203.6 -195.6 -186.2 -206.4 -197.3 -265.4 -203.7 -205.7 -197.0 -194.9 -193.6 -201.1 -200.6 -197.1 -196.0 -196.3 -195.4 -194.2 -198.4 -202.6 -197.1 -209.4 -204.7 -195.9 -192.8 -203.4 -193.3 -188.5 -190.7 -190.3 -197.6 -197.7 -199.1 -193.0 -198.3 -205.0 -191.4 -197.2 -201.3 -197.6 -197.7 -202.9 -203.4 -198.5 -198.8 -205.4 -194.6 -189.5 -193.3 -190.4 -193.0 -202.5 -198.2 -194.7 -198.5 -184.3 -187.8 -193.3 -190.8 -194.9 -190.3 -201.8 -192.9 -198.5 -195.9 -195.8 -210.1 -194.2 -202.6 -194.5 -197.6 -200.1 -191.8 -192.8 -199.4 -199.7 -199.3 -194.2 -196.9 -195.7 -189.9 -197.1 -205.9 -191.1 -196.5 -200.9 -200.6 -199.1 -203.0 -204.2 -198.7 -192.2 -194.9 -188.6 -194.3 -198.5 -190.6 -189.4 -205.8 -207.0 -200.9 -198.0 -196.9 -196.6 -187.3 -199.9 -196.1 -196.5 -200.0 -186.0 -182.7 -193.3 -195.2 -190.0 -195.9 -190.0 -201.7 -187.1 -199.1 -203.5 -191.8 -199.5 -195.1 -207.3 -205.6 -191.9 -200.1 -196.5 -205.4 -190.8 -195.9 -194.6 -190.2 -197.4 -204.4 -210.5 -289.6 -197.2 -191.4 -199.2 -196.6 -201.4 -191.7 -194.4 -191.9 -193.1 -182.9 -191.5 -202.0 -186.8 -195.5 -193.4 -189.8 -181.3 -199.9 -200.3 -193.5 -196.5 -190.5 -200.6 -209.8 -197.7 -199.5 -200.9 -205.0 -199.4 -206.3 -205.7 -202.7 -189.0 -203.6 -198.9 -188.4 -193.7 -204.1 -198.4 -208.8 -201.4 -198.0 -188.7 -208.9 -196.9 -235.5 -198.1 -202.8 -195.8 -193.2 -203.0 -204.2 -201.2 -201.4 -202.8 -213.8 -197.2 -197.0 -191.2 -196.2 -210.8 -203.5 -193.4 -211.7 -194.0 -204.6 -197.0 -200.0 -197.9 -204.2 -196.6 -184.4 -188.6 -194.4 -188.1 -202.4 -203.0 -204.4 -194.1 -195.8 -195.3 -201.9 -194.7 -205.8 -201.9 -208.6 -195.5 -209.5 -194.8 -202.7 -202.2 -204.4 -197.1 -205.9 -196.2 -197.1 -197.4 -198.6 -198.8 -201.1 -203.9 -200.3 -199.5 -224.5 -199.2 -196.2 -197.7 -194.7 -194.1 -202.5 -191.2 -203.1 -199.1 -197.5 -201.0 -198.7 -207.9 -191.7 -192.1 -191.7 -208.7 -178.3 -202.0 -200.4 -202.1 -206.8 -194.2 -197.0 -203.3 -195.1 -210.0 -193.9 -191.1 -200.1 -192.9 -202.3 -189.5 -193.9 -200.8 -205.5 -198.7 -205.4 -184.7 -198.6 -189.7 -187.8 -202.5 -196.2 -203.5 -213.4 -199.7 -207.5 -207.3 -204.7 -190.5 -194.9 -184.7 -198.0 -200.9 -189.8 -208.9 -189.5 -218.6 -202.8 -189.0 -202.2 -204.3 -191.5 -193.6 -201.6 -204.6 -197.0 -200.9 -186.0 -205.9 -194.1 -203.3 -197.3 -200.3 -195.9 -207.3 -206.7 -206.7 -193.0 -203.1 -238.1 -192.2 -193.3 -197.4 -212.3 -202.5 -197.5 -204.1 -196.6 -183.8 -204.5 -188.1 -217.6 -194.5 -199.1 -210.9 -200.9 -187.7 -199.2 -195.0 -191.0 -198.3 -194.1 -191.9 -213.8 -199.0 -201.8 -197.5 -201.5 -195.6 -207.5 -200.6 -194.2 -210.5 -192.7 -188.1 -203.0 -237.1 -204.7 -205.1 -205.2 -200.3 -188.5 -202.2 -213.1 -195.0 -201.4 -204.2 -195.9 -186.5 -192.2 -206.5 -177.5 -189.9 -192.0 -214.9 -204.0 -194.2 -200.9 -197.1 -200.0 -196.4 -197.2 -189.0 -194.3 -206.5 -192.5 -190.5 -204.1 -196.7 -194.4 -181.9 -193.0 -190.6 -193.6 -178.0 -178.2 -200.9 -189.5 -194.2 -182.1 -183.6 -183.7 -176.9 -181.7 -194.9 -190.7 -187.4 -178.6 -182.0 -186.5 -183.7 -182.1 -186.2 -199.6 -192.4 -189.2 -194.7 -176.3 -184.6 -203.2 -201.9 -195.2 -192.7 -186.7 -195.2 -187.0 -201.1 -202.1 -187.7 -195.9 -181.7 -189.7 -179.9 -177.3 -180.3 -198.3 -184.6 -183.3 -196.9 -178.6 -184.3 -185.3 -183.2 -193.9 -194.7 -195.5 -199.6 -192.0 -189.4 -195.0 -193.6 -200.5 -177.6 -181.0 -200.0 -190.3 -189.7 -205.5 -178.5 -201.7 -192.7 -196.8 -189.2 -177.6 -198.0 -191.8 -178.6 -206.8 -190.0 -192.3 -180.1 -194.6 -179.7 -207.1 -195.6 -200.5 -186.7 -190.1 -178.6 -205.7 -346.2 -188.8 -204.4 -200.7 -176.5 -193.8 -195.9 -193.0 -186.5 -189.5 -190.6 -178.0 -188.6 -186.7 -180.9 -193.8 -194.0 -180.6 -196.7 -178.7 -180.1 -187.7 -179.6 -201.3 -219.2 -184.0 -206.3 -186.7 -192.0 -179.4 -190.1 -187.0 -191.6 -194.7 -195.5 -194.2 -195.8 -200.6 -180.3 -195.6 -209.9 -197.2 -201.1 -196.9 -186.3 -202.7 -182.7 -200.4 -201.2 -196.2 -181.1 -182.6 -187.2 -225.3 -186.8 -197.6 -192.0 -185.0 -199.8 -191.7 -187.4 -192.5 -189.1 -210.9 -187.0 -191.2 -190.9 -207.1 -198.7 -208.8 -190.6 -193.7 -186.5 -182.9 -178.7 -194.1 -184.3 -194.0 -185.4 -215.7 -194.6 -207.9 -204.7 -183.7 -189.3 -196.0 -202.6 -206.2 -190.1 -216.6 -179.8 -206.9 -188.4 -190.8 -181.7 -197.7 -195.7 -178.3 -179.0 -179.3 -203.2 -178.4 -180.1 -175.7 -194.1 -193.0 -203.2 -192.6 -194.0 -190.7 -193.0 -194.2 -183.7 -197.2 -188.4 -176.1 -184.3 -192.2 -195.7 -186.0 -193.7 -196.2 -183.7 -180.7 -181.0 -189.4 -199.3 -201.5 -199.8 -197.2 -201.7 -199.9 -192.2 -188.2 -187.5 -176.6 -205.3 -199.0 -190.0 -202.4 -201.8 -216.8 -208.2 -197.4 -194.3 -205.9 -179.0 -193.5 -182.9 -188.0 -198.3 -197.7 -177.6 -183.8 -182.3 -198.8 -192.5 -183.2 -208.4 -192.4 -193.8 -198.6 -196.2 -183.9 -186.2 -197.8 -180.6 -204.7 -195.3 -182.8 -192.5 -216.3 -203.8 -197.4 -179.5 -188.5 -196.8 -194.4 -189.2 -199.8 -200.7 -205.1 -183.4 -181.5 -193.6 -207.9 -177.4 -191.5 -197.3 -189.8 -191.9 -189.5 -201.2 -211.0 -201.4 -205.5 -201.1 -199.3 -193.5 -203.5 -191.6 -194.0 -196.7 -188.5 -189.8 -195.9 -181.1 -193.2 -197.2 -201.0 -186.2 -200.9 -183.5 -183.0 -207.9 -189.7 -193.8 -182.9 -232.1 -186.2 -200.3 -194.6 -184.2 -192.2 -182.9 -193.6 -207.4 -203.3 -185.6 -197.6 -205.9 -193.0 -182.3 -190.1 -193.3 -200.2 -183.9 -195.7 -186.9 -200.1 -189.6 -194.2 -195.5 -178.3 -183.9 -183.0 -179.2 -209.8 -199.6 -185.4 -210.9 -188.6 -188.9 -185.4 -177.0 -183.0 -186.1 -191.7 -190.7 -192.1 -195.2 -185.0 -186.6 -194.2 -189.5 -187.7 -187.9 -191.8 -181.1 -180.2 -180.0 -185.6 -181.8 -187.9 -192.9 -198.7 -182.0 -182.7 -175.8 -202.0 -190.6 -195.3 -191.0 -201.4 -194.3 -179.5 -185.0 -240.3 -187.1 -197.8 -204.8 -210.7 -203.2 -202.0 -197.8 -203.5 -205.1 -190.0 -190.3 -204.1 -197.9 -198.6 -199.3 -182.1 -200.8 -196.0 -197.1 -203.5 -198.6 -200.7 -201.1 -189.1 -175.8 -199.9 -203.7 -192.2 -182.5 -185.0 -195.9 -204.1 -197.0 -195.5 -202.0 -201.5 -187.1 -186.7 -198.2 -211.8 -197.6 -178.5 -198.5 -196.4 -188.1 -185.0 -199.5 -200.9 -201.7 -193.5 -188.3 -180.9 -190.6 -202.8 -183.9 -190.1 -205.3 -198.6 -183.2 -198.0 -200.9 -198.8 -194.8 -198.3 -195.8 -204.6 -202.6 -207.0 -185.9 -201.9 -195.9 -207.6 -197.4 -206.7 -188.2 -184.7 -183.9 -198.3 -186.4 -191.0 -208.8 -209.4 -187.7 -208.0 -198.4 -191.9 -187.1 -188.5 -189.2 -190.7 -179.9 -204.1 -195.5 -183.7 -183.1 -183.7 -194.6 -187.9 -183.5 -184.7 -203.2 -197.8 -179.4 -185.8 -205.3 -179.8 -194.8 -186.7 -191.5 -197.4 -197.0 -209.2 -194.1 -187.8 -192.9 -202.2 -194.4 -206.6 -191.6 -190.8 -187.5 -193.5 -205.2 -185.1 -185.6 -189.9 -196.0 -203.6 -195.4 -209.9 -196.5 -200.8 -190.1 -191.5 -232.8 -209.2 -193.1 -183.4 -199.5 -187.2 -199.4 -203.6 -198.3 -204.1 -196.4 -202.0 -180.6 -191.6 -202.9 -184.9 -180.8 -192.3 -205.2 -205.5 -179.0 -183.3 -203.1 -184.1 -188.6 -180.9 -195.8 -195.0 -181.1 -198.3 -190.7 -191.8 -192.1 -191.5 -257.4 -197.3 -206.5 -213.4 -184.2 -193.5 -208.6 -209.8 -192.0 -201.5 -198.6 -205.2 -198.9 -212.6 -195.9 -213.7 -215.9 -209.2 -215.2 -207.4 -208.9 -192.2 -192.3 -193.8 -185.1 -206.0 -179.1 -199.9 -198.3 -201.6 -186.8 -202.3 -190.4 -183.6 -191.8 -190.6 -194.7 -184.1 -184.4 -193.8 -194.0 -195.6 -204.5 -194.9 -196.1 -201.1 -196.1 -210.9 -198.7 -192.1 -208.3 -192.8 -193.6 -205.1 -191.5 -190.7 -179.2 -191.6 -192.1 -182.3 -176.1 -185.5 -187.1 -183.4 -191.9 -176.1 -178.0 -185.2 -191.3 -181.3 -178.1 -181.7 -200.3 -187.5 -201.6 -192.3 -177.7 -180.6 -192.9 -185.4 -183.1 -178.4 -196.9 -191.9 -186.1 -195.7 -177.7 -184.1 -195.4 -184.2 -188.8 -179.6 -182.0 -182.9 -185.1 -183.8 -189.3 -216.9 -196.6 -185.7 -235.5 -184.9 -181.8 -180.0 -186.6 -188.4 -190.7 -185.4 -210.9 -184.1 -203.0 -203.5 -198.9 -204.2 -199.7 -182.1 -178.1 -205.1 -179.4 -184.5 -180.7 -200.5 -197.3 -178.2 -178.8 -180.9 -219.2 -180.2 -192.5 -198.6 -238.0 -201.1 -182.4 -203.3 -182.0 -188.9 -201.2 -184.6 -182.7 -187.7 -188.5 -202.5 -199.8 -189.4 -191.1 -181.2 -191.7 -194.6 -181.3 -185.3 -192.8 -182.4 -191.6 -188.3 -202.6 -212.1 -179.6 -185.9 -183.4 -187.8 -184.4 -186.8 -197.0 -191.3 -186.7 -201.9 -187.2 -195.7 -178.5 -187.3 -190.8 -198.4 -198.8 -189.1 -189.6 -197.6 -201.0 -185.0 -182.2 -184.2 -193.2 -191.6 -187.4 -196.3 -190.7 -184.5 -206.1 -200.7 -193.0 -196.2 -195.1 -177.1 -180.7 -187.3 -188.3 -181.5 -180.7 -216.9 -185.7 -196.1 -193.2 -185.5 -186.9 -190.4 -189.7 -196.1 -193.9 -193.6 -185.7 -190.3 -199.8 -190.4 -187.4 -195.5 -190.0 -188.7 -190.2 -195.6 -195.2 -184.7 -186.9 -187.4 -179.3 -184.7 -206.7 -194.3 -198.9 -179.0 -185.7 -185.2 -206.7 -184.3 -202.8 -183.5 -178.9 -238.3 -181.1 -189.5 -176.7 -178.7 -183.4 -180.3 -192.4 -193.6 -186.6 -190.0 -184.0 -188.5 -188.6 -196.3 -182.2 -191.9 -191.1 -197.7 -188.4 -194.2 -201.7 -204.3 -199.6 -190.7 -183.0 -189.9 -192.9 -187.6 -182.8 -203.3 -189.3 -194.0 -189.4 -188.0 -194.4 -211.7 -186.3 -185.3 -187.2 -182.9 -194.9 -187.4 -190.4 -197.5 -184.5 -184.8 -180.0 -197.9 -205.9 -189.2 -196.5 -188.1 -185.4 -195.5 -185.0 -203.1 -188.6 -202.3 -180.6 -191.3 -204.4 -208.2 -189.2 -226.9 -200.0 -178.8 -181.5 -197.7 -204.1 -184.8 -178.5 -186.5 -190.9 -190.4 -181.4 -189.8 -179.2 -189.8 -179.6 -203.8 -205.4 -184.2 -192.8 -204.7 -186.6 -195.5 -203.7 -197.2 -178.0 -180.3 -187.0 -179.1 -187.5 -187.9 -183.4 -181.8 -184.1 -181.3 -184.0 -180.6 -230.8 -193.0 -190.5 -200.4 -187.9 -175.9 -204.2 -206.5 -183.2 -194.2 -187.2 -200.2 -189.6 -188.6 -188.6 -175.4 -184.2 -174.0 -177.2 -180.6 -181.5 -182.3 -187.1 -180.0 -184.7 -179.3 -195.7 -180.5 -179.5 -184.8 -204.0 -202.1 -178.7 -189.4 -196.4 -190.8 -184.3 -189.2 -182.8 -184.6 -178.4 -183.9 -185.0 -184.6 -179.2 -179.0 -182.4 -197.0 -188.4 -188.5 -196.0 -179.6 -188.1 -180.3 -196.1 -189.0 -178.4 -176.5 -186.4 -179.3 -187.7 -187.9 -184.8 -176.9 -188.7 -182.8 -192.3 -190.0 -197.2 -191.6 -197.8 -182.3 -184.2 -187.3 -188.2 -207.3 -189.2 -190.7 -202.3 -191.7 -195.4 -196.2 -190.1 -204.2 -194.8 -187.8 -209.1 -192.1 -193.1 -199.3 -192.1 -204.9 -190.8 -186.5 -189.3 -181.9 -193.3 -182.4 -195.2 -189.1 -196.8 -200.8 -187.6 -201.1 -197.0 -196.6 -177.7 -188.9 -186.2 -186.0 -199.9 -203.8 -190.2 -190.2 -186.3 -179.1 -198.8 -186.3 -192.4 -201.5 -190.2 -191.0 -178.0 -194.1 -197.9 -189.9 -180.2 -176.2 -193.5 -201.9 -201.3 -200.7 -190.3 -198.4 -186.0 -190.2 -182.7 -186.0 -190.0 -196.8 -193.0 -201.5 -184.7 -187.7 -190.8 -187.2 -183.5 -178.1 -178.9 -195.8 -178.2 -188.0 -177.2 -182.5 -184.2 -180.7 -189.6 -203.4 -181.7 -185.1 -177.5 -180.9 -194.0 -190.1 -190.1 -182.9 -184.4 -201.8 -191.1 -184.9 -197.7 -193.3 -190.3 -197.2 -188.2 -191.5 -190.0 -188.0 -187.5 -182.5 -186.6 -183.6 -193.9 -187.5 -186.9 -197.3 -187.2 -177.2 -186.8 -191.9 -186.9 -198.7 -179.7 -191.7 -193.6 -184.2 -178.4 -187.4 -203.3 -196.8 -195.4 -182.9 -187.7 -189.4 -192.5 -190.0 -190.0 -185.4 -194.6 -183.7 -180.2 -199.6 -190.5 -205.9 -176.4 -182.8 -179.0 -199.9 -186.7 -188.8 -189.5 -189.8 -193.5 -203.0 -183.8 -204.2 -176.4 -206.5 -184.7 -174.9 -183.2 -174.4 -196.2 -179.1 -183.7 -180.2 -174.5 -185.5 -203.5 -174.7 -186.1 -175.1 -198.2 -200.3 -184.2 -180.4 -187.9 -194.3 -194.9 -181.3 -180.2 -186.0 -187.6 -180.2 -188.1 -196.5 -175.9 -184.0 -194.4 -186.3 -207.6 -188.1 -185.2 -207.5 -177.7 -204.2 -203.3 -180.8 -176.0 -181.5 -202.3 -191.6 -186.8 -183.0 -189.7 -191.2 -179.2 -196.2 -185.9 -184.3 -183.3 -186.8 -179.3 -188.6 -184.8 -176.7 -189.6 -177.5 -186.3 -197.2 -178.1 -189.8 -175.8 -178.9 -191.9 -176.9 -186.8 -186.6 -194.1 -179.3 -178.7 -183.9 -220.3 -181.6 -183.7 -196.7 -180.2 -176.9 -189.5 -187.5 -185.8 -184.3 -179.9 -186.0 -178.5 -179.5 -227.6 -187.1 -199.2 -183.4 -177.2 -181.3 -190.7 -197.8 -180.1 -203.4 -198.1 -196.8 -184.3 -188.5 -189.6 -187.9 -200.7 -187.1 -193.3 -183.0 -199.1 -187.3 -181.8 -184.0 -178.0 -198.7 -177.4 -195.6 -184.1 -183.4 -186.0 -183.1 -181.8 -190.6 -188.8 -184.8 -196.5 -186.2 -184.7 -182.6 -187.4 -194.1 -185.3 -181.6 -198.4 -190.1 -200.2 -214.9 -195.1 -192.9 -190.8 -179.4 -194.9 -206.0 -193.2 -186.6 -214.1 -216.1 -189.0 -184.2 -201.1 -182.1 -200.2 -188.5 -193.0 -184.8 -188.8 -186.6 -188.3 -193.9 -202.4 -196.8 -214.5 -202.1 -186.7 -197.3 -184.2 -186.5 -202.6 -187.3 -204.3 -176.1 -183.9 -189.2 -189.7 -180.8 -199.4 -185.7 -193.3 -192.7 -192.8 -204.9 -188.7 -196.5 -187.9 -177.4 -189.6 -177.2 -197.3 -183.9 -189.7 -184.6 -191.0 -195.4 -175.7 -179.1 -184.4 -193.2 -180.4 -191.2 -187.2 -181.1 -203.5 -189.2 -186.4 -176.3 -191.5 -193.6 -187.0 -186.8 -187.3 -184.8 -197.6 -207.3 -191.8 -187.1 -196.3 -206.9 -199.9 -186.3 -189.9 -179.8 -200.0 -193.8 -190.9 -180.9 -176.3 -189.1 -180.4 -190.9 -182.4 -182.8 -181.1 -193.9 -184.0 -185.9 -199.1 -199.5 -204.2 -181.9 -199.0 -184.1 -207.4 -194.8 -216.5 -188.4 -206.7 -199.2 -179.3 -186.7 -200.7 -186.3 -195.5 -204.9 -194.0 -187.5 -196.3 -181.4 -186.0 -197.8 -198.1 -196.1 -184.3 -183.3 -211.3 -192.8 -187.9 -183.4 -192.9 -187.4 -194.2 -177.1 -200.0 -199.3 -177.2 -180.1 -178.6 -182.3 -189.1 -191.3 -197.7 -187.6 -187.3 -203.9 -204.4 -180.4 -186.5 -188.4 -176.1 -206.5 -187.7 -194.1 -193.5 -203.7 -186.8 -200.1 -187.0 -203.3 -196.3 -208.1 -192.7 -202.1 -204.7 -183.9 -186.7 -198.2 -189.4 -186.4 -188.3 -195.2 -203.3 -202.3 -201.1 -180.1 -191.3 -180.4 -187.7 -193.4 -196.5 -208.8 -185.3 -186.8 -203.6 -179.0 -185.0 -181.1 -193.8 -196.9 -201.0 -187.3 -189.6 -190.8 -188.9 -197.6 -203.0 -193.2 -185.6 -195.6 -199.1 -191.8 -178.7 -183.6 -184.1 -192.0 -182.4 -183.8 -209.5 -205.7 -187.0 -187.6 -200.6 -187.1 -187.2 -184.9 -180.3 -189.4 -182.7 -196.8 -184.7 -185.8 -184.0 -194.1 -180.5 -199.1 -181.7 -205.3 -182.6 -186.8 -180.2 -181.9 -187.4 -187.9 -191.8 -204.8 -178.5 -181.6 -181.6 -179.5 -181.9 -190.1 -194.1 -180.0 -179.1 -181.2 -175.0 -186.3 -184.8 -182.6 -186.8 -185.3 -181.2 -190.0 -195.3 -186.9 -190.6 -187.3 -193.4 -176.9 -190.5 -194.6 -181.0 -175.8 -187.9 -183.2 -187.7 -191.4 -183.1 -178.6 -193.4 -185.5 -190.1 -194.6 -191.0 -177.7 -187.3 -201.3 -188.6 -182.5 -196.3 -176.2 -184.9 -189.6 -186.9 -227.9 -188.1 -185.0 -182.9 -196.4 -183.1 -179.8 -186.5 -185.2 -199.7 -187.7 -191.6 -191.9 -194.8 -183.9 -185.3 -188.2 -192.7 -180.8 -183.5 -199.8 -196.8 -184.2 -179.5 -204.2 -183.5 -175.4 -207.3 -192.5 -191.9 -208.6 -194.7 -195.2 -190.3 -180.8 -182.6 -203.2 -191.4 -189.7 -183.9 -185.7 -192.3 -190.7 -206.8 -182.9 -195.2 -193.1 -201.2 -177.0 -188.1 -182.3 -185.0 -198.5 -186.4 -183.9 -189.4 -181.8 -199.9 -198.7 -183.7 -191.8 -187.5 -209.4 -201.8 -178.0 -201.8 -198.0 -187.2 -185.5 -178.1 -195.7 -200.1 -174.8 -176.4 -187.6 -177.3 -178.1 -197.5 -183.7 -207.7 -180.6 -176.6 -190.8 -191.0 -180.1 -180.4 -178.8 -185.5 -194.8 -188.1 -185.8 -179.5 -181.0 -196.1 -192.6 -179.2 -180.7 -206.3 -175.9 -196.8 -179.4 -195.1 -187.5 -183.9 -183.8 -184.6 -208.6 -195.5 -202.9 -191.9 -187.0 -189.2 -178.5 -176.1 -186.6 -195.1 -181.6 -201.0 -192.1 -192.9 -202.2 -191.0 -205.8 -204.3 -191.8 -185.1 -190.1 -193.6 -192.4 -185.2 -180.6 -192.6 -185.7 -187.5 -189.2 -184.0 -189.1 -200.6 -185.2 -182.8 -182.0 -185.4 -178.3 -188.4 -193.2 -194.9 -197.1 -194.4 -184.8 -179.2 -195.6 -182.6 -204.3 -203.1 -180.0 -187.7 -187.7 -197.8 -178.7 -186.5 -194.6 -194.8 -176.4 -202.5 -195.4 -180.5 -220.0 -191.0 -217.1 -178.4 -196.1 -182.5 -190.8 -191.7 -202.0 -196.8 -199.4 -183.8 -183.2 -186.5 -178.1 -198.6 -186.1 -195.4 -196.6 -199.3 -196.5 -177.9 -186.3 -180.5 -198.9 -190.2 -188.5 -184.1 -188.6 -201.4 -185.4 -176.4 -182.0 -176.9 -184.4 -179.0 -178.4 -183.8 -190.9 -185.5 -184.4 -179.6 -197.5 -184.3 -179.1 -193.4 -194.2 -179.1 -189.0 -191.2 -180.8 -184.5 -187.9 -191.7 -177.2 -185.4 -183.6 -190.7 -187.5 -188.8 -199.7 -190.0 -176.0 -204.4 -191.1 -188.3 -182.1 -181.6 -191.4 -191.8 -193.1 -186.0 -188.1 -178.4 -193.7 -175.1 -179.0 -186.7 -185.3 -179.7 -182.7 -198.0 -180.2 -189.5 -183.1 -177.1 -182.3 -174.7 -175.6 -186.4 -189.2 -178.9 -180.4 -181.3 -182.3 -180.3 -180.8 -180.1 -197.2 -204.7 -181.6 -182.3 -184.0 -176.5 -214.9 -194.7 -178.3 -175.1 -174.3 -176.5 -190.9 -183.1 -176.8 -177.1 -183.8 -178.5 -189.2 -180.8 -177.6 -175.3 -185.3 -183.4 -175.2 -183.6 -177.0 -181.9 -180.3 -185.1 -179.1 -188.1 -184.4 -181.6 -188.0 -181.6 -190.6 -177.9 -182.7 -177.4 -183.2 -189.3 -187.6 -179.8 -192.3 -188.1 -194.6 -186.7 -181.6 -191.8 -195.6 -187.4 -185.5 -190.0 -184.0 -178.5 -178.0 -200.8 -199.2 -186.5 -174.9 -181.3 -181.0 -187.6 -186.8 -183.3 -183.8 -195.6 -190.6 -193.8 -176.4 -179.1 -182.9 -193.4 -184.4 -186.2 -180.3 -194.7 -182.6 -186.7 -196.4 -196.7 -196.2 -192.3 -189.1 -178.4 -182.3 -195.2 -184.1 -189.0 -184.7 -189.3 -184.1 -177.3 -189.5 -186.1 -186.4 -180.5 -196.1 -187.5 -188.4 -195.8 -192.0 -192.9 -182.4 -199.6 -189.6 -180.2 -176.1 -220.4 -206.6 -195.5 -176.5 -202.2 -187.5 -185.0 -205.6 -195.7 -192.8 -192.8 -174.9 -187.3 -181.9 -180.4 -183.9 -187.6 -192.5 -202.1 -185.2 -200.2 -184.1 -189.9 -194.7 -185.1 -191.9 -176.0 -197.7 -177.5 -178.6 -179.3 -206.0 -193.3 -196.2 -179.3 -181.3 -205.5 -178.1 -186.9 -183.5 -178.5 -193.1 -179.4 -186.1 -174.3 -194.4 -187.1 -195.8 -176.0 -187.6 -176.1 -183.7 -182.0 -183.7 -176.3 -201.0 -185.8 -180.6 -186.1 -180.1 -204.4 -186.1 -182.9 -181.7 -184.6 -177.3 -186.2 -188.7 -180.5 -182.1 -185.3 -177.7 -185.4 -188.2 -194.1 -185.6 -177.8 -192.7 -198.1 -196.0 -187.5 -186.4 -206.8 -207.4 -177.3 -181.3 -185.0 -175.7 -174.2 -191.5 -194.0 -190.8 -199.2 -176.4 -202.7 -193.1 -182.6 -186.0 -196.0 -186.1 -189.4 -203.4 -184.8 -194.3 -187.2 -183.5 -199.4 -196.7 -180.2 -195.2 -180.9 -182.7 -193.5 -200.0 -193.3 -184.4 -199.1 -206.2 -199.0 -195.8 -189.4 -194.1 -196.4 -201.5 -180.7 -189.7 -193.3 -200.3 -205.5 -189.9 -192.6 -187.1 -205.7 -194.9 -188.0 -189.2 -197.9 -188.5 -185.0 -182.7 -205.8 -186.7 -189.2 -185.1 -182.4 -205.1 -181.4 -185.6 -188.5 -195.9 -199.8 -185.4 -194.7 -201.2 -185.0 -202.1 -200.0 -181.9 -186.8 -195.9 -182.2 -186.6 -187.1 -184.9 -181.1 -190.1 -191.0 -186.7 -184.6 -181.8 -190.4 -185.7 -183.4 -187.0 -182.6 -183.5 -173.9 -181.8 -194.1 -182.2 -182.6 -181.8 -187.0 -192.2 -178.9 -206.9 -197.1 -180.7 -183.4 -176.7 -187.9 -194.5 -182.0 -182.0 -190.9 -177.9 -180.3 -190.8 -187.7 -179.1 -187.9 -183.7 -187.9 -183.5 -175.9 -186.5 -178.2 -180.7 -194.3 -184.8 -181.4 -182.8 -179.8 -187.0 -179.1 -178.8 -187.2 -185.9 -182.0 -187.7 -181.3 -186.0 -181.0 -183.2 -186.5 -189.3 -187.8 -182.8 -179.4 -199.0 -180.9 -193.8 -202.6 -185.8 -177.5 -182.7 -202.4 -213.8 -190.6 -189.8 -190.5 -185.0 -183.7 -191.0 -185.7 -182.2 -194.8 -183.1 -191.8 -186.6 -185.2 -181.7 -182.1 -185.7 -195.0 -181.5 -185.1 -181.5 -187.3 -186.5 -188.7 -185.2 -180.7 -178.3 -191.8 -185.4 -188.6 -184.5 -187.5 -191.5 -191.5 -195.8 -197.9 -194.2 -184.9 -182.7 -182.1 -185.6 -188.4 -178.8 -190.4 -179.3 -186.2 -206.0 -191.2 -195.1 -198.4 -189.9 -180.8 -181.1 -198.5 -203.4 -190.8 -177.1 -184.0 -181.0 -192.2 -175.9 -200.4 -192.2 -181.1 -202.0 -198.6 -203.6 -191.7 -193.4 -192.6 -186.5 -182.4 -195.8 -184.9 -191.0 -176.7 -182.7 -194.8 -181.9 -191.1 -205.5 -176.3 -200.1 -184.1 -208.8 -184.3 -196.2 -190.2 -197.1 -186.8 -181.7 -188.5 -188.6 -187.2 -195.3 -198.6 -205.7 -185.4 -187.5 -176.2 -186.1 -199.4 -294.6 -232.7 -200.5 -181.8 -189.1 -186.9 -190.7 -179.7 -181.3 -181.5 -200.5 -181.2 -181.7 -185.4 -195.5 -201.9 -199.7 -194.2 -179.6 -181.4 -205.5 -183.1 -499.4 -188.5 -184.5 -194.5 -195.5 -193.6 -189.0 -196.4 -188.3 -186.7 -190.6 -176.9 -188.1 -189.4 -198.2 -178.8 -196.5 -203.1 -192.3 -193.8 -188.4 -180.2 -192.3 -187.1 -195.2 -181.6 -185.5 -190.9 -185.2 -200.5 -190.0 -180.2 -194.4 -196.5 -187.7 -184.3 -189.5 -188.2 -189.5 -194.5 -192.4 -202.1 -177.9 -193.8 -191.7 -182.2 -190.1 -197.4 -196.6 -193.7 -195.9 -200.9 -178.8 -181.4 -193.6 -193.5 -177.7 -192.9 -190.9 -201.2 -184.9 -175.8 -197.9 -202.4 -192.3 -202.5 -198.3 -196.8 -185.2 -184.8 -198.1 -191.3 -174.0 -180.5 -193.4 -183.0 -185.1 -177.0 -190.4 -181.3 -179.0 -180.6 -179.1 -188.8 -207.2 -183.7 -186.6 -198.3 -176.6 -186.5 -187.4 -179.5 -189.2 -197.7 -181.5 -194.6 -195.5 -181.6 -197.3 -190.7 -202.0 -183.9 -193.0 -183.9 -196.9 -203.5 -189.4 -187.1 -185.2 -184.8 -199.8 -175.7 -180.6 -187.6 -185.4 -178.5 -185.5 -178.7 -187.5 -185.7 -191.9 -180.2 -186.7 -183.0 -196.7 -197.6 -197.1 -187.4 -194.8 -194.7 -191.0 -185.1 -187.0 -185.8 -197.6 -204.2 -187.9 -189.9 -217.5 -202.8 -192.4 -176.4 -178.8 -199.8 -192.5 -199.9 -190.8 -202.8 -187.0 -180.2 -196.6 -176.5 -187.6 -181.3 -191.0 -180.6 -184.7 -195.8 -191.5 -182.7 -181.3 -189.3 -182.5 -184.2 -187.9 -202.4 -195.7 -189.5 -195.4 -201.2 -186.1 -208.8 -199.6 -189.4 -180.5 -194.2 -184.5 -187.5 -196.6 -188.0 -210.1 -193.3 -187.6 -191.6 -188.5 -179.2 -192.5 -189.7 -181.6 -180.9 -187.9 -180.6 -181.1 -178.7 -175.7 -176.2 -187.1 -185.0 -186.9 -186.5 -190.0 -185.6 -201.2 -189.3 -189.3 -189.7 -188.2 -187.2 -175.0 -185.5 -185.0 -205.2 -187.3 -177.2 -179.2 -190.2 -183.0 -192.9 -183.2 -185.4 -179.2 -186.2 -183.1 -183.8 -186.6 -185.7 -192.4 -179.6 -196.2 -180.2 -185.9 -197.4 -192.2 -177.5 -180.7 -190.2 -176.9 -193.6 -186.2 -184.9 -182.0 -186.1 -187.4 -184.3 -196.2 -203.1 -180.6 -192.5 -196.2 -195.9 -181.6 -189.9 -183.3 -192.7 -187.3 -191.0 -200.2 -180.1 -187.0 -175.7 -179.9 -193.1 -190.2 -202.1 -174.1 -179.5 -185.1 -182.7 -196.7 -179.8 -186.7 -192.5 -189.2 -193.7 -184.1 -185.6 -184.6 -193.6 -181.0 -189.2 -179.9 -181.4 -183.7 -184.5 -193.1 -191.5 -182.9 -190.2 -185.2 -185.9 -216.6 -184.1 -195.7 -181.2 -182.8 -199.3 -187.4 -184.9 -177.6 -206.2 -184.1 -201.5 -200.7 -192.2 -187.0 -182.1 -196.6 -181.6 -189.2 -191.6 -188.8 -186.9 -193.6 -184.2 -191.3 -194.9 -194.6 -188.7 -179.2 -205.1 -181.0 -177.3 -183.7 -184.8 -183.7 -204.3 -190.7 -181.6 -191.6 -189.5 -195.5 -176.0 -193.0 -192.1 -195.9 -205.8 -192.2 -190.6 -198.3 -185.8 -186.7 -198.6 -184.2 -203.1 -199.6 -187.0 -204.3 -207.2 -190.8 -196.7 -188.8 -193.2 -188.7 -199.8 -204.3 -188.6 -192.0 -209.8 -180.3 -203.7 -196.4 -185.7 -182.1 -193.3 -200.9 -196.6 -181.9 -182.2 -179.2 -197.3 -189.3 -200.9 -184.5 -185.8 -185.6 -187.5 -187.5 -189.5 -186.9 -187.2 -195.7 -182.0 -179.0 -191.4 -188.5 -177.7 -185.7 -182.0 -189.0 -198.7 -188.4 -186.6 -180.4 -185.1 -184.2 -207.6 -184.2 -190.0 -181.5 -190.9 -191.2 -187.8 -177.8 -182.7 -191.8 -206.2 -201.4 -182.2 -189.2 -195.4 -187.9 -195.7 -190.4 -183.3 -183.2 -178.2 -189.0 -179.2 -175.5 -187.3 -181.1 -180.1 -188.1 -184.4 -183.9 -200.2 -185.4 -180.4 -184.0 -183.8 -181.2 -203.6 -201.1 -197.1 -192.3 -182.7 -182.4 -183.0 -177.3 -181.3 -185.3 -184.6 -188.7 -179.1 -179.1 -184.6 -176.0 -177.8 -186.9 -189.8 -180.3 -177.2 -184.2 -179.2 -177.4 -182.0 -186.6 -188.7 -194.2 -184.0 -178.9 -175.3 -191.6 -182.9 -188.3 -178.7 -201.6 -186.4 -180.8 -184.7 -186.7 -196.9 -177.7 -178.8 -175.3 -182.7 -184.0 -182.4 -196.6 -174.7 -178.0 -181.5 -198.1 -185.1 -177.5 -181.2 -188.1 -196.0 -183.6 -196.2 -185.9 -193.2 -186.7 -179.7 -195.3 -190.1 -206.8 -186.2 -178.5 -192.0 -187.6 -176.9 -191.8 -190.8 -193.6 -200.0 -192.3 -178.0 -184.6 -179.4 -178.2 -183.2 -179.9 -184.9 -183.7 -189.1 -176.4 -185.5 -184.8 -192.5 -185.3 -193.9 -179.6 -181.7 -179.1 -210.8 -185.6 -184.2 -181.3 -198.8 -180.2 -182.5 -191.9 -196.4 -186.6 -185.3 -182.5 -175.8 -182.0 -186.9 -186.6 -176.0 -175.4 -186.5 -175.4 -182.4 -199.5 -192.7 -182.0 -199.9 -181.1 -196.7 -186.2 -182.0 -175.9 -184.4 -183.8 -178.4 -191.3 -177.8 -196.1 -200.8 -200.6 -191.1 -190.4 -180.3 -200.6 -201.4 -181.3 -176.9 -183.2 -185.0 -178.4 -187.8 -172.7 -182.8 -186.3 -193.9 -179.2 -194.9 -176.8 -188.1 -190.7 -192.3 -178.4 -191.9 -196.6 -183.5 -197.8 -192.0 -176.0 -192.1 -191.5 -193.3 -209.5 -185.2 -187.6 -186.3 -190.9 -183.9 -190.2 -186.3 -184.7 -177.3 -185.0 -178.3 -193.0 -181.7 -190.9 -185.3 -174.9 -192.3 -194.5 -194.1 -177.0 -185.2 -193.2 -202.4 -202.0 -197.2 -199.3 -176.9 -185.7 -188.1 -186.8 -184.4 -204.5 -196.4 -181.3 -190.9 -177.2 -192.4 -179.9 -177.0 -194.1 -203.5 -189.1 -194.7 -181.5 -183.6 -199.8 -187.3 -185.1 -195.7 -177.8 -178.3 -189.8 -200.1 -176.9 -177.9 -188.9 -190.9 -198.7 -197.7 -186.9 -190.8 -201.4 -188.5 -180.4 -196.2 -185.8 -194.9 -193.3 -181.3 -195.4 -197.5 -201.3 -179.5 -177.7 -201.9 -199.9 -183.5 -177.6 -190.4 -183.7 -178.4 -203.6 -195.9 -199.5 -193.2 -175.0 -184.5 -190.6 -194.3 -178.2 -177.5 -188.4 -179.7 -183.8 -174.2 -186.5 -179.8 -196.9 -194.9 -178.4 -185.7 -190.1 -181.3 -180.0 -179.9 -181.7 -187.4 -185.9 -178.9 -184.6 -189.5 -186.6 -185.8 -188.4 -188.3 -174.7 -184.9 -192.5 -185.3 -174.9 -180.6 -179.5 -183.4 -177.7 -177.5 -187.4 -183.7 -188.0 -177.6 -180.7 -180.9 -181.9 -188.9 -201.1 -186.6 -176.3 -177.3 -177.6 -175.6 -201.5 -175.5 -188.2 -181.8 -176.9 -185.3 -179.6 -192.7 -203.8 -183.4 -179.4 -177.9 -182.8 -182.3 -174.9 -180.5 -180.2 -187.1 -190.4 -185.5 -184.6 -185.4 -190.3 -183.9 -180.0 -201.8 -198.1 -184.2 -192.8 -184.2 -195.7 -191.4 -188.8 -192.9 -184.8 -174.3 -191.8 -185.4 -183.8 -192.7 -192.6 -194.8 -177.9 -178.7 -181.5 -177.3 -192.5 -176.0 -178.9 -199.7 -181.0 -178.8 -177.1 -183.0 -176.7 -182.3 -180.9 -183.1 -183.9 -174.2 -178.7 -173.8 -174.4 -179.1 -178.4 -175.4 -181.4 -180.9 -178.2 -182.5 -184.2 -183.7 -182.6 -176.2 -177.2 -180.5 -183.9 -193.4 -174.9 -178.8 -176.0 -178.1 -176.1 -177.3 -178.7 -182.2 -191.0 -186.8 -188.4 -180.3 -177.8 -198.8 -176.7 -198.3 -178.5 -177.9 -179.9 -186.7 -178.0 -175.4 -186.6 -190.8 -190.7 -183.5 -196.3 -182.1 -184.4 -188.8 -186.3 -184.8 -191.3 -186.2 -191.0 -188.3 -178.8 -176.3 -181.2 -183.1 -180.4 -178.6 -176.2 -176.1 -177.5 -180.6 -178.1 -176.4 -195.4 -178.8 -179.6 -178.1 -179.7 -178.3 -181.9 -177.4 -181.4 -186.7 -174.6 -179.4 -177.5 -197.6 -196.5 -193.1 -179.2 -182.2 -178.1 -186.3 -182.1 -175.4 -177.5 -188.1 -182.9 -179.8 -179.2 -180.0 -176.9 -177.4 -192.5 -177.5 -177.4 -181.8 -175.6 -178.9 -180.6 -176.8 -182.8 -186.7 -182.5 -188.3 -183.7 -185.1 -195.4 -179.2 -180.7 -190.0 -187.5 -180.3 -183.0 -184.2 -184.3 -189.4 -180.1 -179.6 -182.3 -177.6 -186.3 -188.0 -182.1 -187.1 -186.2 -184.2 -202.3 -187.0 -188.0 -180.5 -194.6 -188.8 -190.7 -181.9 -182.1 -185.3 -183.1 -197.3 -195.0 -208.3 -195.7 -179.1 -196.3 -185.5 -185.4 -186.9 -193.9 -187.1 -184.2 -180.0 -184.8 -189.6 -192.3 -185.6 -185.8 -185.9 -187.9 -186.2 -177.3 -192.2 -201.9 -185.9 -181.7 -192.8 -185.4 -187.3 -187.5 -178.9 -187.6 -181.3 -186.9 -179.6 -179.3 -189.4 -177.5 -184.5 -176.4 -193.3 -178.7 -191.6 -182.7 -194.6 -187.4 -190.4 -199.1 -191.6 -193.1 -187.0 -181.7 -180.3 -196.6 -180.5 -180.0 -184.9 -176.9 -176.3 -179.3 -189.1 -180.4 -176.0 -174.9 -181.2 -177.6 -177.4 -177.6 -179.0 -178.7 -178.7 -184.8 -177.9 -179.4 -183.8 -181.9 -177.1 -175.8 -182.9 -183.2 -176.8 -181.7 -183.7 -192.1 -178.2 -181.4 -180.0 -176.8 -179.8 -194.3 -181.6 -180.7 -177.5 -187.4 -179.0 -180.0 -186.0 -182.0 -175.4 -178.9 -181.9 -192.0 -179.5 -178.5 -175.3 -184.1 -178.3 -177.1 -186.2 -196.9 -182.0 -178.0 -181.4 -181.4 -179.6 -180.2 -180.4 -183.1 -176.6 -182.9 -176.3 -191.5 -179.9 -178.1 -178.4 -189.3 -196.8 -188.2 -180.5 -185.2 -188.0 -176.3 -181.0 -187.4 -178.9 -179.1 -185.3 -183.4 -185.8 -178.5 -176.1 -188.9 -200.9 -193.9 -193.4 -184.0 -187.2 -178.1 -193.5 -182.0 -180.1 -182.8 -176.8 -177.0 -184.0 -185.2 -197.3 -180.8 -190.4 -177.3 -183.4 -191.3 -175.4 -176.8 -192.3 -177.3 -191.1 -185.1 -179.7 -190.8 -175.9 -181.2 -194.0 -176.5 -180.3 -175.1 -185.1 -181.3 -200.0 -187.0 -182.6 -182.0 -176.8 -190.1 -182.1 -181.7 -192.3 -177.0 -185.1 -181.3 -179.2 -182.1 -176.6 -185.0 -177.4 -183.5 -196.5 -184.2 -179.2 -180.5 -180.8 -181.9 -176.9 -178.6 -175.9 -192.0 -198.7 -189.6 -190.5 -186.3 -192.6 -196.0 -176.2 -175.9 -176.5 -195.4 -174.8 -177.4 -186.7 -174.9 -176.1 -183.0 -178.1 -177.4 -192.9 -179.7 -198.5 -178.1 -178.6 -195.4 -181.6 -179.9 -179.5 -186.4 -180.6 -180.3 -187.3 -193.9 -192.5 -178.1 -184.8 -194.9 -194.6 -181.4 -177.6 -180.4 -175.5 -180.5 -177.2 -186.6 -176.8 -176.3 -186.0 -179.8 -178.2 -177.9 -178.9 -190.1 -180.8 -180.1 -181.3 -193.5 -185.0 -198.7 -199.9 -183.4 -177.3 -176.2 -182.7 -178.2 -175.2 -177.7 -186.9 -182.1 -195.1 -181.3 -182.4 -175.7 -185.5 -180.8 -181.4 -181.6 -190.1 -183.7 -186.4 -194.3 -176.4 -176.7 -189.9 -175.6 -206.6 -178.9 -180.0 -178.8 -180.1 -184.1 -176.3 -177.9 -194.3 -188.5 -182.6 -178.6 -177.5 -190.9 -178.9 -180.3 -193.9 -187.4 -186.4 -190.1 -184.7 -199.2 -187.9 -177.7 -180.5 -189.4 -176.5 -192.8 -181.4 -178.0 -193.6 -175.8 -184.4 -184.1 -191.9 -176.2 -184.5 -180.4 -185.1 -180.0 -192.6 -187.6 -190.2 -183.0 -176.5 -194.4 -178.4 -184.5 -176.6 -179.0 -182.6 -187.2 -180.4 -183.3 -180.8 -179.1 -193.9 -181.9 -188.8 -180.0 -175.2 -194.5 -194.8 -187.7 -182.5 -199.3 -175.0 -175.9 -177.9 -179.6 -179.4 -176.0 -176.4 -175.8 -177.2 -176.8 -179.0 -180.4 -177.1 -174.9 -177.9 -180.6 -187.3 -176.6 -177.3 -184.4 -179.2 -177.2 -175.7 -183.3 -177.4 -180.7 -175.6 -173.6 -179.6 -177.2 -180.8 -176.4 -187.7 -178.4 -176.0 -192.5 -181.4 -183.5 -178.5 -186.6 -179.4 -180.1 -181.6 -178.3 -178.2 -184.1 -180.6 -178.3 -184.1 -181.6 -177.4 -183.4 -180.6 -178.8 -179.0 -175.1 -177.0 -180.8 -179.9 -177.7 -176.3 -177.3 -184.2 -176.9 -190.8 -183.0 -181.0 -184.0 -178.6 -175.2 -177.2 -177.9 -183.2 -180.9 -176.3 -177.0 -182.8 -178.5 -176.9 -178.1 -175.5 -184.7 -176.6 -177.2 -182.4 -189.5 -197.3 -179.9 -190.4 -182.4 -188.7 -185.5 -181.1 -182.6 -187.0 -184.4 -179.1 -180.1 -180.9 -187.2 -175.9 -194.1 -177.9 -177.4 -200.7 -201.4 -183.5 -180.8 -195.5 -181.0 -180.2 -181.5 -175.9 -175.3 -180.1 -182.1 -180.1 -176.5 -178.9 -200.5 -178.6 -176.6 -175.8 -175.8 -176.0 -199.3 -177.5 -180.9 -185.1 -200.3 -194.0 -177.7 -181.2 -182.1 -185.1 -183.4 -180.7 -188.8 -187.3 -179.1 -177.5 -185.5 -185.5 -177.2 -175.3 -178.6 -184.5 -180.0 -179.9 -177.1 -178.0 -187.8 -183.6 -189.6 -181.5 -179.7 -179.0 -188.8 -185.1 -177.0 -177.1 -176.3 -176.4 -199.6 -178.1 -188.2 -176.9 -191.5 -194.0 -182.6 -184.0 -186.4 -184.1 -180.0 -181.1 -187.3 -176.1 -174.5 -189.3 -188.9 -178.7 -177.2 -191.0 -194.3 -187.7 -177.0 -176.4 -183.3 -176.2 -181.3 -181.0 -176.8 -187.8 -178.2 -202.3 -191.6 -180.3 -174.8 -187.8 -176.9 -176.9 -181.1 -177.5 -186.1 -179.3 -187.2 -176.6 -178.6 -178.7 -179.0 -188.7 -188.5 -183.8 -192.2 -178.8 -180.4 -182.1 -177.0 -175.1 -180.1 -176.7 -176.0 -188.1 -191.3 -186.6 -202.0 -182.5 -175.9 -182.1 -195.6 -174.8 -194.5 -181.2 -191.8 -180.4 -178.7 -186.1 -180.9 -186.4 -177.0 -183.6 -179.7 -208.1 -179.4 -179.1 -178.5 -179.2 -180.7 -183.3 -180.4 -187.6 -176.9 -185.4 -187.5 -184.3 -183.5 -181.0 -190.8 -178.6 -180.0 -180.4 -191.0 -182.8 -186.9 -179.6 -189.1 -186.9 -202.3 -181.1 -192.1 -194.3 -176.7 -185.8 -177.3 -179.5 -177.2 -177.8 -190.5 -190.1 -184.1 -191.8 -178.7 -185.9 -178.3 -177.4 -176.4 -177.8 -179.0 -177.6 -179.7 -178.1 -190.5 -177.8 -180.4 -181.6 -181.3 -177.3 -182.1 -189.7 -178.2 -179.7 -181.3 -178.8 -194.0 -200.6 -179.6 -177.9 -181.0 -184.7 -180.8 -181.1 -187.8 -183.4 -186.2 -181.8 -175.8 -176.8 -176.3 -177.0 -186.7 -178.5 -183.0 -177.1 -182.3 -182.2 -180.6 -180.6 -185.2 -178.9 -192.3 -177.6 -212.1 -180.5 -186.4 -187.4 -196.4 -181.9 -194.5 -188.5 -179.4 -179.3 -181.4 -185.7 -176.9 -182.6 -185.0 -181.7 -178.9 -184.4 -180.4 -189.2 -187.5 -204.6 -189.7 -182.6 -182.1 -180.0 -182.3 -180.1 -189.3 -178.1 -183.8 -180.9 -184.8 -182.2 -177.7 -176.1 -197.5 -195.8 -183.3 -183.4 -199.0 -205.4 -183.6 -182.5 -182.2 -199.1 -187.1 -179.5 -182.9 -180.2 -177.5 -183.4 -189.4 -196.2 -181.2 -183.3 -178.6 -181.5 -185.5 -179.8 -184.3 -198.8 -184.9 -178.0 -177.7 -181.0 -186.0 -196.3 -178.1 -192.4 -178.7 -181.4 -192.5 -181.4 -192.5 -182.2 -178.9 -183.9 -185.3 -192.2 -186.0 -193.4 -178.4 -194.5 -179.9 -187.6 -185.9 -179.2 -185.0 -188.1 -189.4 -187.9 -190.0 -191.9 -187.5 -186.0 -189.6 -182.4 -185.6 -187.0 -192.4 -183.3 -189.2 -194.6 -195.9 -190.7 -186.4 -185.9 -185.3 -177.1 -184.6 -186.4 -183.1 -186.2 -180.0 -181.8 -184.7 -176.6 -178.0 -178.5 -182.2 -200.3 -184.2 -186.9 -178.2 -190.3 -194.9 -193.1 -193.5 -188.5 -177.9 -185.4 -177.6 -179.7 -193.0 -200.3 -182.0 -192.3 -183.3 -183.6 -183.2 -190.8 -182.6 -177.7 -177.1 -183.7 -177.5 -175.4 -180.3 -181.3 -178.8 -182.3 -176.5 -177.4 -176.0 -178.8 -184.3 -183.0 -180.2 -184.9 -188.1 -187.6 -182.8 -183.0 -180.0 -177.5 -196.1 -185.1 -175.5 -175.9 -178.6 -201.5 -177.1 -191.7 -184.8 -176.2 -184.4 -175.9 -182.6 -182.0 -180.8 -178.7 -191.3 -179.5 -178.7 -174.8 -185.1 -174.9 -189.8 -191.3 -191.9 -190.7 -175.8 -177.3 -183.6 -178.0 -185.1 -177.2 -178.6 -188.7 -179.0 -186.0 -202.6 -177.2 -179.8 -196.0 -195.8 -186.8 -183.6 -202.2 -182.0 -175.8 -186.6 -178.2 -181.3 -180.8 -183.6 -181.9 -192.4 -190.8 -179.2 -184.6 -186.2 -183.0 -196.5 -179.6 -183.4 -187.2 -179.5 -185.3 -182.2 -177.8 -176.6 -177.2 -179.3 -177.1 -181.9 -178.9 -180.2 -179.8 -175.0 -176.8 -180.5 -175.7 -176.3 -180.6 -181.6 -176.6 -175.4 -177.4 -176.2 -180.8 -188.0 -178.2 -205.6 -177.8 -176.5 -179.4 -176.4 -183.3 -177.9 -174.2 -176.1 -182.8 -180.8 -186.9 -179.4 -195.8 -178.8 -181.6 -199.7 -175.8 -186.7 -179.1 -182.4 -179.1 -176.3 -180.5 -174.7 -180.8 -178.2 -185.2 -183.3 -192.7 -184.9 -205.8 -177.0 -182.5 -187.3 -185.9 -184.3 -177.0 -193.2 -179.0 -177.5 -181.3 -176.2 -178.8 -197.3 -180.8 -180.8 -189.7 -188.3 -179.5 -179.3 -185.3 -184.8 -192.3 -180.4 -186.7 -180.0 -178.9 -177.9 -179.4 -177.3 -181.9 -175.4 -174.1 -180.2 -176.9 -178.6 -177.5 -176.4 -177.7 -180.6 -182.2 -178.0 -179.3 -176.9 -188.6 -180.4 -179.8 -180.7 -177.2 -176.7 -175.3 -176.4 -178.4 -177.8 -180.1 -193.5 -181.0 -183.6 -177.9 -181.9 -186.9 -197.3 -175.7 -177.6 -184.7 -179.6 -182.2 -181.9 -181.2 -176.7 -185.5 -196.8 -185.9 -182.4 -178.1 -180.2 -178.3 -181.7 -186.4 -175.6 -182.6 -179.6 -181.0 -188.0 -178.1 -176.9 -181.0 -179.6 -185.0 -177.7 -179.4 -178.0 -185.7 -179.0 -194.2 -175.4 -178.5 -175.0 -176.7 -179.3 -188.8 -181.0 -177.3 -188.0 -178.5 -180.0 -175.9 -180.7 -181.2 -177.0 -179.2 -179.3 -193.1 -176.0 -179.4 -185.4 -177.4 -177.2 -177.9 -176.4 -186.7 -178.0 -178.7 -180.5 -186.7 -176.4 -185.8 -182.5 -177.3 -180.3 -179.5 -174.6 -184.2 -184.0 -176.3 -176.0 -211.4 -184.5 -182.1 -180.5 -188.1 -177.9 -179.7 -177.5 -184.5 -180.6 -191.1 -187.4 -176.3 -180.4 -183.2 -184.8 -178.6 -189.8 -180.9 -176.6 -176.9 -176.4 -182.0 -178.2 -177.3 -189.9 -191.1 -178.0 -179.5 -176.7 -194.2 -211.7 -175.9 -177.9 -176.0 -179.7 -180.6 -176.4 -180.3 -177.2 -183.6 -180.6 -187.4 -189.4 -189.6 -177.1 -179.4 -184.3 -186.4 -181.9 -180.1 -184.8 -182.0 -188.2 -181.4 -184.8 -177.5 -180.3 -195.4 -185.7 -176.8 -176.0 -187.3 -202.2 -194.5 -181.1 -182.9 -197.6 -186.9 -181.3 -180.9 -183.9 -191.0 -182.5 -186.9 -179.7 -179.2 -185.6 -184.3 -180.4 -190.9 -183.6 -183.1 -175.0 -180.9 -186.3 -174.8 -176.4 -176.1 -175.7 -178.1 -178.0 -180.5 -182.6 -180.0 -179.2 -186.8 -188.3 -179.8 -179.6 -180.5 -176.9 -204.2 -195.2 -180.2 -177.9 -187.9 -191.3 -183.9 -185.3 -186.8 -182.5 -189.5 -176.8 -180.5 -189.3 -185.9 -178.0 -176.0 -179.2 -181.3 -175.6 -179.9 -179.4 -183.8 -178.8 -177.9 -180.1 -182.3 -180.9 -175.7 -178.1 -173.7 -177.9 -180.0 -176.2 -177.7 -179.4 -192.3 -175.7 -185.7 -188.6 -195.5 -182.5 -184.1 -177.9 -177.8 -183.0 -174.9 -174.9 -179.7 -186.4 -185.9 -175.2 -179.2 -176.8 -181.5 -178.3 -180.6 -176.8 -175.8 -175.9 -180.3 -179.7 -175.8 -174.1 -180.6 -176.7 -179.7 -175.7 -179.2 -178.3 -203.4 -177.9 -186.9 -175.7 -177.0 -178.8 -180.2 -180.1 -185.5 -175.0 -178.6 -183.3 -177.2 -178.3 -180.1 -175.9 -175.6 -179.3 -179.8 -178.0 -186.5 -176.4 -187.2 -181.6 -175.4 -177.5 -179.1 -179.2 -175.9 -174.3 -175.5 -177.4 -178.5 -182.0 -181.4 -184.4 -183.4 -174.4 -177.5 -175.0 -175.4 -174.1 -182.8 -184.9 -178.3 -182.9 -182.3 -186.6 -180.9 -191.6 -185.6 -184.8 -190.2 -175.8 -185.2 -175.5 -176.9 -176.7 -176.9 -176.5 -179.2 -179.9 -179.2 -177.8 -188.9 -180.3 -186.8 -182.0 -180.8 -176.6 -180.5 -175.3 -185.0 -181.1 -181.1 -176.5 -176.5 -178.0 -175.9 -180.2 -178.3 -188.0 -185.9 -178.6 -179.5 -187.6 -180.2 -181.3 -182.5 -182.8 -175.0 -184.9 -181.7 -178.5 -177.5 -177.1 -176.8 -179.0 -179.2 -175.5 -177.1 -178.9 -174.8 -179.0 -177.3 -179.2 -178.2 -177.5 -191.8 -177.6 -182.1 -178.7 -177.2 -182.5 -181.5 -185.6 -179.5 -183.9 -177.6 -179.6 -193.9 -175.9 -216.0 -180.4 -177.3 -178.8 -176.7 -177.3 -178.3 -188.8 -175.8 -175.7 -176.0 -178.3 -185.1 -179.0 -191.3 -180.0 -178.8 -189.8 -182.7 -176.7 -178.0 -184.2 -185.0 -190.3 -178.0 -178.7 -177.4 -186.0 -176.4 -179.6 -178.0 -182.2 -175.9 -175.7 -178.3 -174.7 -193.6 -177.2 -186.6 -183.7 -181.0 -192.1 -176.4 -188.6 -205.9 -199.0 -194.6 -193.4 -190.4 -178.1 -188.0 -183.8 -180.5 -180.5 -190.5 -194.5 -180.8 -185.3 -193.4 -183.1 -178.1 -197.4 -190.2 -181.0 -184.9 -189.0 -184.6 -183.7 -187.7 -187.9 -182.5 -192.6 -184.3 -178.7 -179.8 -196.8 -184.4 -195.5 -183.9 -186.6 -181.0 -188.7 -185.0 -197.1 -204.2 -176.8 -179.6 -185.3 -182.1 -178.6 -180.6 -183.0 -199.1 -180.5 -180.7 -189.2 -194.5 -187.1 -192.3 -179.3 -196.8 -197.3 -180.3 -177.0 -178.8 -183.2 -183.1 -176.6 -201.6 -183.8 -182.7 -177.0 -185.2 -180.1 -199.4 -203.2 -187.4 -185.7 -184.1 -183.0 -198.7 -186.3 -187.9 -199.4 -185.9 -190.3 -202.8 -204.6 -178.1 -187.6 -196.5 -180.3 -181.7 -182.9 -199.2 -198.8 -190.5 -219.6 -180.0 -203.5 -182.0 -184.1 -176.8 -200.9 -201.9 -180.9 -177.9 -183.4 -179.5 -197.8 -188.0 -204.1 -185.6 -179.3 -190.6 -184.3 -195.2 -188.0 -200.9 -187.7 -183.0 -180.9 -180.0 -184.7 -176.8 -181.9 -180.6 -180.0 -177.7 -182.2 -175.2 -182.9 -186.3 -203.4 -183.3 -175.8 -186.2 -179.8 -178.4 -178.2 -420.1 -177.9 -193.8 -183.8 -180.0 -188.8 -187.2 -192.0 -180.8 -182.3 -191.8 -183.2 -176.6 -179.5 -215.2 -193.8 -188.3 -180.3 -186.4 -181.8 -205.8 -175.1 -186.5 -205.9 -185.5 -187.1 -191.7 -189.4 -188.3 -180.1 -179.8 -178.9 -179.3 -181.9 -184.9 -188.4 -176.2 -177.0 -181.8 -179.5 -177.3 -176.0 -208.3 -185.6 -180.6 -180.3 -195.0 -177.7 -175.7 -214.3 -188.2 -177.7 -187.1 -197.1 -184.8 -178.2 -182.1 -178.4 -176.3 -190.6 -187.3 -177.8 -177.2 -191.7 -200.2 -188.4 -177.3 -177.0 -178.5 -180.3 -177.0 -182.2 -184.4 -175.8 -185.6 -179.6 -180.8 -179.9 -199.4 -175.1 -196.3 -185.5 -182.5 -179.4 -191.2 -192.4 -180.3 -186.8 -194.7 -180.5 -178.0 -180.8 -184.9 -180.7 -179.0 -184.5 -180.5 -176.2 -182.9 -178.8 -183.5 -194.6 -182.0 -198.5 -176.5 -185.0 -187.6 -196.9 -194.2 -185.0 -190.8 -179.6 -175.8 -198.5 -180.0 -177.9 -203.3 -183.3 -181.4 -183.8 -176.5 -175.1 -193.9 -178.9 -183.0 -180.2 -178.0 -178.9 -188.1 -181.3 -179.3 -181.6 -183.1 -175.0 -178.8 -175.7 -179.4 -180.6 -185.9 -176.7 -190.8 -189.6 -180.1 -176.7 -181.7 -180.7 -191.9 -175.5 -180.1 -185.1 -182.0 -181.0 -184.3 -196.6 -188.8 -191.0 -184.2 -184.1 -180.1 -189.0 -178.2 -182.6 -190.4 -182.5 -186.3 -182.9 -191.5 -183.6 -193.2 -183.3 -201.4 -215.5 -182.4 -196.6 -183.6 -190.7 -180.8 -190.9 -178.2 -189.8 -194.8 -180.9 -184.2 -184.1 -185.3 -176.7 -181.5 -181.0 -191.1 -195.9 -192.0 -178.0 -179.9 -184.7 -181.3 -188.5 -187.6 -184.7 -193.9 -198.5 -188.5 -186.5 -184.4 -188.1 -183.0 -190.8 -184.9 -183.8 -184.5 -185.5 -180.2 -181.3 -181.8 -177.5 -178.6 -205.8 -188.5 -188.1 -183.9 -182.9 -192.0 -181.9 -181.5 -190.2 -185.2 -188.1 -174.3 -190.1 -185.6 -183.3 -182.1 -192.2 -179.6 -179.7 -187.5 -187.3 -187.1 -180.0 -184.2 -180.6 -311.7 -185.9 -185.9 -185.1 -176.8 -176.4 -177.7 -177.1 -188.2 -174.8 -184.0 -178.6 -180.2 -183.4 -182.9 -189.8 -187.3 -176.8 -192.5 -186.1 -212.1 -179.4 -181.3 -188.4 -177.7 -200.4 -182.7 -177.5 -183.5 -187.5 -182.6 -194.0 -179.6 -181.6 -201.6 -183.0 -185.5 -177.8 -200.1 -182.7 -182.1 -192.5 -185.6 -188.8 -180.8 -179.5 -181.1 -185.1 -178.1 -178.9 -183.1 -180.8 -178.7 -184.8 -180.1 -179.7 -187.2 -187.1 -182.5 -187.0 -185.6 -191.9 -187.7 -186.3 -188.0 -180.1 -179.3 -181.3 -193.7 -176.8 -184.4 -176.7 -183.1 -189.4 -178.8 -211.4 -182.2 -190.8 -194.1 -179.4 -176.3 -178.6 -175.5 -182.9 -186.0 -184.1 -187.8 -181.3 -188.4 -178.3 -178.7 -200.4 -176.0 -187.7 -197.2 -188.2 -188.6 -192.3 -180.3 -186.3 -187.6 -201.5 -183.8 -182.9 -185.8 -185.9 -181.9 -180.2 -177.3 -183.3 -186.4 -181.3 -195.4 -194.0 -182.7 -178.3 -190.5 -178.6 -194.5 -175.4 -176.8 -177.4 -191.1 -180.6 -175.5 -175.2 -186.9 -176.1 -183.6 -187.1 -178.4 -196.0 -201.0 -183.0 -179.7 -179.9 -184.1 -179.9 -193.1 -180.8 -187.2 -182.0 -176.1 -183.4 -188.4 -177.6 -177.3 -183.8 -179.5 -184.4 -179.8 -181.5 -178.6 -186.5 -183.1 -175.7 -177.3 -177.5 -194.3 -190.9 -175.4 -198.2 -182.6 -180.9 -182.7 -177.0 -190.4 -186.8 -199.4 -183.6 -180.4 -196.3 -205.0 -178.0 -182.0 -185.0 -180.0 -200.6 -185.4 -186.6 -188.4 -199.1 -183.3 -211.8 -182.2 -186.0 -186.5 -185.4 -183.8 -182.3 -179.9 -182.0 -186.9 -184.6 -187.9 -182.4 -187.3 -199.6 -187.9 -196.6 -189.9 -190.9 -180.9 -177.5 -180.2 -188.4 -181.4 -178.0 -190.8 -198.7 -191.5 -189.8 -191.4 -188.6 -186.2 -198.8 -207.4 -192.2 -185.0 -194.7 -198.7 -191.4 -197.4 -184.9 -202.5 -178.6 -180.3 -186.9 -184.5 -178.3 -179.4 -201.3 -193.5 -184.2 -193.9 -177.1 -185.8 -188.5 -183.6 -201.0 -183.6 -190.9 -190.3 -185.4 -180.2 -185.9 -182.6 -184.7 -182.1 -188.7 -180.5 -178.0 -198.6 -188.8 -183.8 -178.1 -176.4 -179.4 -179.5 -186.5 -180.4 -179.8 -180.2 -195.0 -177.2 -180.0 -195.5 -181.7 -183.6 -187.1 -180.7 -180.7 -181.2 -184.5 -181.0 -199.1 -197.4 -183.6 -189.0 -183.2 -196.4 -183.7 -191.4 -185.3 -202.8 -177.9 -182.1 -179.5 -176.3 -193.1 -184.6 -178.8 -191.8 -224.8 -180.5 -182.0 -178.8 -178.2 -178.8 -185.4 -186.5 -178.6 -188.4 -179.7 -190.9 -181.6 -179.8 -190.1 -188.0 -179.7 -204.8 -184.8 -179.7 -182.5 -184.1 -176.1 -181.1 -177.2 -185.8 -177.7 -179.1 -186.7 -183.8 -177.5 -180.2 -200.9 -181.0 -182.7 -177.7 -191.7 -176.8 -190.9 -178.6 -182.3 -178.8 -186.1 -176.8 -180.0 -182.5 -175.0 -183.2 -177.4 -189.5 -177.7 -179.1 -180.8 -177.9 -180.0 -181.6 -178.6 -178.1 -184.7 -176.8 -176.0 -175.7 -175.9 -180.3 -176.3 -180.4 -178.8 -182.5 -177.9 -187.7 -182.2 -187.2 -178.5 -179.9 -181.1 -180.9 -182.5 -179.8 -178.6 -176.0 -179.0 -189.5 -183.5 -182.5 -183.6 -186.0 -181.7 -191.1 -187.4 -194.0 -197.2 -197.3 -177.9 -179.4 -178.0 -176.9 -178.6 -189.0 -183.3 -188.5 -184.0 -184.0 -185.5 -180.7 -176.3 -180.2 -179.9 -186.7 -177.5 -181.0 -189.3 -190.3 -178.3 -188.1 -189.5 -183.6 -190.7 -178.9 -179.1 -179.5 -196.1 -180.8 -178.9 -177.9 -184.6 -178.0 -181.9 -185.3 -187.5 -183.9 -187.0 -180.1 -198.9 -182.6 -181.1 -191.1 -190.7 -183.6 -181.2 -184.5 -177.3 -179.5 -178.7 -181.5 -180.1 -185.0 -178.6 -182.8 -182.7 -192.6 -181.5 -176.5 -178.4 -187.0 -180.2 -187.5 -182.5 -178.0 -184.6 -180.3 -187.2 -177.6 -187.5 -190.6 -188.2 -187.8 -182.6 -186.8 -179.0 -211.0 -176.2 -180.5 -183.4 -215.3 -181.6 -208.2 -215.6 -207.8 -189.1 -176.5 -190.9 -187.0 -178.8 -190.2 -183.0 -193.6 -175.3 -184.4 -184.2 -181.7 -175.4 -177.4 -176.1 -187.1 -194.1 -181.3 -193.1 -182.1 -184.7 -183.1 -186.0 -180.6 -181.7 -181.7 -184.9 -191.4 -201.1 -181.7 -192.9 -177.6 -187.6 -177.6 -183.6 -195.4 -187.2 -184.2 -185.4 -178.0 -201.0 -180.0 -205.9 -201.9 -199.2 -185.2 -182.7 -181.0 -187.4 -181.5 -186.6 -180.4 -176.7 -177.9 -178.2 -179.3 -186.5 -175.7 -185.5 -195.1 -181.9 -183.3 -182.0 -176.7 -181.0 -176.1 -179.4 -186.2 -194.1 -191.1 -184.0 -185.1 -188.6 -183.2 -176.1 -179.3 -183.6 -177.5 -192.7 -180.6 -191.3 -182.6 -189.3 -183.6 -182.4 -178.8 -175.5 -179.3 -193.2 -181.3 -183.9 -185.1 -183.3 -184.9 -188.6 -185.7 -194.9 -199.5 -175.7 -202.6 -194.2 -185.3 -178.0 -182.5 -202.3 -187.5 -192.9 -181.8 -183.2 -183.5 -187.8 -179.6 -178.7 -197.1 -182.2 -202.2 -194.8 -184.9 -192.6 -175.5 -178.0 -184.7 -177.8 -178.7 -179.7 -181.4 -186.6 -179.3 -178.9 -182.3 -180.8 -180.5 -182.4 -184.0 -183.2 -181.2 -183.6 -186.2 -179.7 -178.6 -200.2 -189.2 -177.5 -188.0 -191.1 -183.2 -183.4 -191.0 -186.9 -198.9 -180.0 -175.3 -261.0 -178.7 -181.1 -181.2 -178.7 -179.1 -201.6 -178.4 -181.6 -176.2 -181.7 -192.2 -184.5 -179.1 -191.8 -181.3 -184.4 -185.0 -186.6 -178.6 -180.2 -185.2 -190.0 -177.3 -178.5 -193.7 -178.7 -184.8 -179.9 -192.0 -186.2 -194.7 -181.5 -183.9 -188.0 -183.4 -181.3 -187.2 -184.6 -188.7 -185.3 -180.1 -183.4 -182.4 -176.9 -177.6 -191.1 -180.8 -176.0 -175.4 -180.0 -179.6 -188.3 -191.3 -183.2 -181.7 -177.9 -180.0 -182.0 -181.3 -180.1 -187.7 -177.5 -186.7 -183.4 -189.1 -199.9 -203.9 -184.1 -179.2 -187.4 -185.7 -181.8 -179.7 -179.1 -175.6 -200.8 -181.2 -175.9 -179.3 -176.9 -183.8 -195.7 -185.6 -181.9 -184.0 -190.1 -188.6 -179.0 -181.7 -179.2 -212.9 -181.3 -192.8 -180.8 -180.4 -190.8 -178.1 -181.2 -183.4 -189.4 -191.6 -196.7 -179.2 -203.5 -197.4 -180.5 -184.2 -194.9 -182.6 -183.3 -177.9 -200.4 -191.9 -175.4 -214.3 -184.1 -180.8 -182.9 -181.3 -182.4 -181.4 -191.0 -178.9 -188.3 -195.6 -182.1 -193.5 -180.3 -196.3 -177.9 -198.8 -190.9 -179.1 -185.4 -188.7 -181.0 -177.8 -178.0 -203.4 -179.4 -180.8 -183.6 -179.0 -184.8 -178.0 -188.3 -203.1 -194.9 -196.8 -187.9 -185.7 -178.0 -180.8 -176.8 -181.0 -180.9 -187.0 -179.5 -186.9 -175.9 -174.7 -177.1 -187.9 -193.2 -177.3 -177.9 -181.2 -180.1 -176.1 -179.4 -176.7 -183.2 -191.8 -184.7 -180.8 -183.2 -176.9 -182.8 -187.5 -187.3 -185.7 -184.6 -178.8 -183.0 -176.7 -177.6 -198.0 -194.7 -188.8 -180.9 -187.9 -175.9 -193.1 -183.4 -186.2 -184.4 -182.3 -175.6 -224.3 -186.0 -184.0 -179.0 -176.6 -183.9 -190.9 -188.5 -183.9 -184.7 -198.6 -184.1 -182.0 -181.3 -183.3 -181.6 -182.8 -186.6 -181.4 -179.0 -192.0 -186.3 -202.8 -190.0 -182.1 -186.4 -186.0 -187.0 -192.8 -185.4 -185.4 -181.2 -182.3 -183.2 -190.4 -184.9 -186.4 -180.9 -181.4 -179.8 -191.3 -182.4 -193.0 -202.1 -187.9 -222.0 -196.9 -201.9 -197.8 -198.7 -184.1 -192.7 -203.2 -197.1 -193.7 -196.5 -186.3 -198.4 -181.2 -192.3 -190.4 -183.3 -181.9 -201.8 -198.5 -194.7 -182.3 -184.9 -186.0 -185.9 -190.8 -179.4 -182.2 -181.7 -180.6 -179.2 -180.9 -189.7 -195.7 -200.7 -191.6 -191.1 -187.6 -181.6 -185.9 -188.3 -183.5 -187.7 -190.3 -186.1 -181.1 -178.7 -178.0 -179.0 -191.5 -186.8 -184.9 -181.0 -183.4 -181.3 -180.1 -188.2 -204.3 -180.1 -185.8 -184.9 -187.4 -176.0 -184.2 -177.6 -179.0 -178.9 -188.3 -179.8 -180.9 -177.5 -188.9 -191.1 -184.7 -189.5 -178.4 -189.3 -184.7 -186.2 -178.9 -176.6 -180.8 -177.3 -183.3 -180.0 -188.8 -186.8 -179.5 -179.6 -181.6 -177.4 -176.5 -178.0 -182.6 -184.7 -189.3 -183.6 -180.6 -186.6 -180.7 -185.6 -178.2 -176.3 -181.2 -177.6 -175.7 -177.3 -184.0 -178.2 -182.9 -201.6 -175.0 -179.3 -181.6 -176.2 -180.4 -176.0 -183.7 -177.5 -183.5 -193.5 -192.7 -179.0 -182.2 -179.6 -179.3 -176.8 -177.9 -177.2 -176.5 -177.4 -177.9 -186.5 -178.9 -181.0 -178.0 -176.6 -176.5 -179.2 -187.2 -178.2 -184.6 -178.9 -177.8 -182.1 -187.2 -188.8 -184.5 -181.0 -188.4 -193.1 -178.7 -186.2 -181.1 -183.2 -181.4 -177.6 -176.7 -177.1 -179.0 -181.0 -177.9 -183.5 -181.6 -178.9 -179.4 -175.8 -175.6 -179.0 -180.1 -175.9 -179.9 -178.1 -186.0 -208.0 -178.6 -182.7 -186.3 -174.5 -178.6 -184.3 -185.4 -178.3 -178.5 -190.5 -180.8 -188.2 -177.3 -190.1 -175.5 -188.5 -185.4 -179.6 -181.4 -177.4 -217.5 -196.9 -180.8 -179.9 -192.5 -178.0 -178.4 -175.8 -175.3 -184.8 -197.2 -186.0 -176.9 -176.5 -178.4 -180.8 -185.5 -203.5 -183.3 -180.0 -177.6 -181.2 -180.2 -179.7 -194.4 -180.8 -181.3 -176.9 -187.2 -178.5 -178.7 -185.4 -183.0 -181.3 -261.7 -178.1 -175.9 -175.9 -189.8 -185.9 -184.1 -181.7 -182.7 -177.6 -176.6 -183.6 -178.4 -178.5 -185.8 -184.5 -178.5 -178.0 -181.7 -177.4 -179.3 -177.5 -175.7 -176.6 -176.4 -180.8 -184.9 -177.6 -178.0 -178.7 -178.0 -177.8 -176.7 -183.6 -196.4 -182.4 -182.2 -178.0 -175.9 -179.2 -175.6 -178.3 -176.2 -178.8 -183.1 -175.2 -182.4 -180.6 -177.6 -176.6 -180.2 -180.4 -181.1 -176.2 -188.7 -187.2 -181.6 -181.5 -177.2 -176.9 -177.4 -176.3 -185.2 -178.3 -184.6 -178.3 -189.7 -179.5 -201.1 -176.2 -185.5 -182.2 -183.4 -174.5 -176.8 -180.1 -179.8 -182.2 -178.8 -186.5 -188.2 -180.4 -182.1 -182.8 -194.7 -182.3 -177.6 -176.2 -180.7 -193.6 -178.9 -177.8 -178.7 -179.8 -176.3 -180.8 -184.2 -181.5 -179.2 -178.2 -179.9 -176.7 -180.0 -183.0 -180.6 -177.3 -186.7 -180.8 -181.5 -190.3 -186.8 -184.2 -180.4 -181.6 -182.2 -183.0 -173.3 -187.5 -185.7 -180.1 -177.8 -189.2 -194.9 -176.8 -194.9 -187.0 -209.2 -185.4 -177.7 -178.0 -175.4 -178.0 -183.1 -177.9 -182.4 -177.2 -177.7 -178.9 -183.5 -178.1 -179.2 -191.5 -182.6 -179.8 -182.5 -176.9 -180.2 -176.0 -178.6 -184.7 -279.2 -179.0 -176.5 -180.0 -182.9 -178.3 -188.1 -179.6 -177.8 -175.6 -180.0 -178.6 -181.0 -184.0 -178.2 -191.6 -176.8 -187.7 -179.1 -183.3 -203.5 -178.7 -178.6 -175.4 -187.5 -179.7 -181.6 -177.9 -180.5 -186.7 -182.3 -187.9 -182.2 -187.8 -181.1 -266.6 -186.3 -185.9 -178.0 -180.6 -176.9 -176.5 -177.0 -184.1 -182.7 -179.0 -182.6 -180.8 -179.9 -179.0 -183.1 -178.6 -176.4 -177.3 -176.4 -180.2 -177.2 -177.0 -177.5 -178.3 -175.2 -177.8 -176.7 -181.4 -177.7 -177.1 -176.5 -180.8 -177.2 -178.1 -177.9 -187.1 -183.8 -187.0 -184.4 -180.2 -179.2 -179.2 -178.6 -188.0 -184.7 -178.0 -176.3 -175.3 -181.6 -191.8 -176.9 -182.0 -183.3 -177.5 -185.0 -181.5 -182.6 -179.0 -188.4 -203.6 -184.3 -183.8 -188.0 -189.7 -184.7 -185.9 -195.0 -185.3 -178.8 -190.6 -181.6 -180.1 -187.1 -182.3 -176.8 -179.1 -185.8 -180.1 -180.3 -182.7 -185.3 -175.6 -182.8 -188.5 -175.6 -182.7 -182.0 -179.5 -180.9 -179.4 -183.2 -182.7 -182.5 -182.0 -190.1 -199.7 -177.8 -177.6 -180.9 -181.6 -183.3 -186.1 -188.0 -184.9 -185.4 -182.6 -182.5 -178.7 -185.6 -175.4 -176.7 -182.5 -180.6 -178.3 -179.7 -184.4 -180.9 -184.5 -187.2 -181.6 -192.7 -185.9 -179.6 -184.3 -182.3 -175.0 -180.3 -177.2 -177.9 -178.4 -179.7 -174.6 -190.4 -193.1 -186.8 -180.6 -176.0 -177.4 -188.4 -179.2 -180.9 -178.7 -180.9 -178.2 -176.6 -185.0 -182.1 -181.7 -175.2 -175.1 -183.2 -192.0 -188.3 -182.1 -176.7 -177.6 -177.3 -192.6 -189.3 -178.2 -177.5 -183.1 -183.4 -181.2 -179.5 -175.4 -176.8 -178.2 -175.8 -179.4 -184.7 -184.6 -191.9 -177.4 -176.7 -179.3 -181.6 -183.3 -176.6 -218.6 -175.7 -174.4 -186.4 -185.1 -176.0 -195.2 -180.3 -178.1 -179.2 -178.0 -181.5 -182.9 -179.0 -191.3 -185.1 -186.5 -177.2 -180.3 -191.0 -175.7 -179.8 -182.0 -181.6 -185.0 -183.2 -174.8 -184.5 -182.1 -178.7 -186.7 -186.9 -176.5 -184.5 -188.9 -180.4 -190.1 -181.4 -188.0 -193.5 -187.7 -180.0 -183.5 -176.7 -177.5 -179.2 -206.2 -178.4 -183.2 -181.7 -200.9 -193.1 -176.1 -181.8 -183.6 -193.5 -201.7 -188.0 -178.9 -180.5 -180.8 -176.5 -178.0 -180.6 -181.4 -184.7 -192.4 -177.4 -182.4 -202.8 -189.7 -177.3 -181.5 -178.7 -180.0 -180.6 -178.0 -178.3 -183.9 -177.4 -180.0 -189.7 -175.4 -185.2 -179.3 -184.1 -177.5 -182.1 -174.8 -179.8 -187.5 -216.9 -182.9 -183.5 -203.3 -181.5 -184.0 -181.3 -183.4 -180.3 -176.1 -180.3 -180.1 -180.2 -181.2 -182.3 -176.2 -189.5 -219.7 -180.1 -176.6 -177.3 -178.8 -181.2 -175.1 -183.3 -182.1 -178.7 -180.9 -183.3 -188.1 -225.2 -185.8 -184.3 -187.5 -187.3 -190.7 -181.0 -180.2 -184.6 -177.9 -180.1 -187.6 -181.1 -177.5 -184.5 -176.5 -182.7 -174.5 -183.2 -176.5 -183.0 -177.0 -179.2 -182.9 -184.9 -176.4 -179.9 -183.2 -178.1 -177.0 -205.5 -182.5 -175.2 -185.0 -182.7 -178.2 -189.0 -190.5 -178.8 -183.5 -185.1 -181.3 -181.3 -194.5 -187.8 -184.9 -177.2 -179.6 -195.1 -181.2 -188.8 -180.4 -180.8 -180.0 -177.6 -198.3 -180.6 -179.5 -178.4 -179.3 -177.5 -176.8 -181.6 -183.8 -181.8 -175.6 -181.0 -178.4 -179.4 -179.8 -181.3 -181.1 -193.3 -180.1 -182.8 -179.3 -181.1 -188.3 -177.6 -178.5 -178.8 -177.1 -179.2 -181.6 -185.6 -191.8 -176.3 -187.8 -184.5 -197.3 -183.1 -179.7 -178.1 -181.3 -177.6 -178.2 -179.5 -177.5 -185.4 -184.4 -186.4 -177.4 -178.0 -179.7 -177.9 -184.6 -189.1 -184.5 -197.2 -192.6 -188.0 -186.5 -177.3 -183.7 -183.7 -192.8 -181.2 -199.4 -179.7 -187.7 -192.8 -208.5 -184.1 -175.6 -185.3 -188.6 -183.7 -180.7 -182.1 -176.0 -183.1 -179.6 -175.7 -187.0 -179.9 -184.8 -179.4 -187.6 -181.6 -201.1 -193.5 -186.2 -190.3 -197.9 -208.2 -192.9 -193.1 -184.9 -210.5 -178.6 -198.2 -177.9 -192.2 -181.6 -185.1 -189.1 -188.3 -204.7 -186.2 -179.6 -189.2 -176.9 -180.5 -183.3 -193.1 -178.4 -203.8 -185.2 -180.6 -183.3 -186.7 -188.8 -184.4 -181.7 -186.4 -185.8 -180.1 -182.7 -179.8 -198.9 -180.4 -178.3 -195.6 -184.0 -179.5 -181.8 -187.4 -181.7 -181.8 -175.1 -200.0 -181.6 -203.0 -176.0 -184.9 -199.3 -178.2 -184.3 -176.6 -192.9 -188.1 -185.7 -181.0 -179.5 -183.4 -186.7 -178.6 -183.2 -179.6 -182.6 -177.3 -179.0 -197.0 -182.0 -174.8 -179.4 -180.7 -210.3 -211.3 -235.3 -255.7 -275.7 -286.8 -306.7 -347.2 -381.2 -184.5 -186.7 -190.1 -193.3 -177.9 -188.0 -184.0 -180.6 -178.5 -235.8 -179.6 -178.1 -196.0 -180.5 -179.0 -185.8 -230.8 -211.1 -178.3 -179.4 -186.5 -180.6 -181.4 -183.2 -188.7 -184.8 -175.0 -179.2 -185.4 -180.8 -182.7 -183.1 -177.3 -177.4 -181.3 -190.9 -182.7 -198.2 -180.9 -200.5 -188.4 -207.5 -190.2 -178.9 -184.1 -193.6 -321.3 -183.8 -181.4 -174.6 -185.1 -198.9 -202.2 -183.3 -187.3 -183.0 -184.5 -178.3 -183.8 -176.7 -178.3 -186.0 -181.0 -176.0 -181.3 -202.8 -179.7 -180.3 -191.6 -176.8 -182.6 -183.7 -181.3 -186.2 -205.7 -186.4 -181.9 -189.9 -188.9 -193.6 -203.2 -212.3 -178.9 -181.5 -189.6 -178.9 -177.6 -189.0 -177.3 -177.2 -178.0 -178.5 -177.9 -197.8 -182.0 -185.7 -193.6 -185.8 -183.1 -183.1 -192.7 -183.0 -187.0 -193.4 -186.9 -182.3 -183.9 -201.6 -199.5 -182.7 -184.6 -181.8 -179.1 -189.8 -183.1 -187.8 -185.7 -192.9 -179.3 -179.7 -180.2 -177.6 -180.8 -178.0 -190.2 -177.5 -199.2 -192.7 -181.2 -185.2 -183.5 -198.1 -178.9 -183.7 -191.6 -187.4 -180.5 -211.9 -206.2 -183.2 -182.1 -176.7 -187.4 -176.6 -183.2 -195.5 -178.7 -180.7 -181.2 -189.1 -187.8 -183.1 -181.9 -186.3 -197.1 -184.7 -177.2 -180.5 -179.5 -181.6 -177.9 -187.7 -196.2 -189.5 -180.5 -183.3 -180.6 -186.7 -186.2 -177.7 -192.1 -182.4 -177.5 -179.7 -193.6 -200.1 -179.9 -188.4 -182.3 -190.4 -179.4 -182.4 -181.7 -195.7 -177.2 -181.3 -182.9 -188.3 -183.6 -180.3 -192.7 -183.1 -210.5 -185.1 -183.4 -191.6 -187.9 -183.1 -175.5 -177.4 -183.7 -182.9 -188.5 -180.7 -186.2 -182.4 -186.3 -182.4 -188.1 -180.2 -195.4 -181.8 -192.9 -176.3 -177.7 -178.8 -179.4 -182.6 -180.3 -187.4 -185.3 -183.5 -180.5 -180.8 -182.0 -178.9 -176.2 -197.0 -181.5 -177.1 -189.1 -188.0 -176.5 -181.7 -184.9 -192.2 -181.5 -189.0 -204.6 -177.5 -176.6 -202.2 -176.9 -181.9 -177.9 -180.6 -197.2 -175.9 -175.6 -183.4 -182.7 -191.2 -178.8 -187.2 -178.9 -192.4 -178.6 -178.4 -184.5 -216.4 -190.7 -182.7 -181.6 -199.5 -182.0 -179.1 -189.1 -180.3 -182.0 -185.6 -196.1 -182.5 -180.4 -190.9 -178.9 -186.3 -209.4 -181.7 -186.6 -192.0 -200.0 -205.7 -191.0 -186.0 -185.5 -176.2 -191.4 -184.4 -186.1 -186.6 -180.0 -180.8 -178.0 -180.0 -198.8 -183.9 -183.5 -176.4 -176.7 -181.4 -186.4 -186.8 -186.0 -179.5 -187.2 -179.5 -185.2 -179.4 -183.6 -188.6 -179.8 -179.0 -184.4 -178.4 -177.4 -195.2 -207.0 -184.3 -179.6 -183.1 -184.0 -187.2 -181.4 -178.4 -182.7 -189.4 -183.1 -179.7 -181.8 -181.5 -181.9 -182.6 -178.2 -189.2 -189.1 -190.3 -184.1 -195.3 -176.1 -177.3 -186.8 -183.7 -188.5 -179.7 -177.4 -181.4 -180.7 -206.9 -179.2 -177.8 -180.5 -180.6 -191.9 -181.7 -190.3 -183.5 -186.2 -175.8 -179.1 -181.6 -181.6 -183.0 -179.1 -179.3 -183.7 -181.2 -185.2 -176.8 -177.8 -175.3 -184.6 -179.2 -176.9 -188.0 -184.6 -184.6 -180.9 -189.9 -396.3 -176.1 -183.1 -179.2 -184.6 -181.5 -181.3 -176.2 -177.4 -174.3 -179.4 -178.8 -184.6 -182.1 -183.4 -178.4 -184.1 -182.7 -181.4 -177.7 -185.0 -177.2 -179.4 -183.5 -183.1 -187.6 -181.1 -179.7 -189.6 -183.6 -177.1 -181.5 -193.1 -196.8 -180.2 -177.3 -178.8 -176.6 -177.8 -190.0 -176.3 -180.1 -177.5 -187.2 -186.7 -176.5 -179.6 -177.2 -177.5 -196.4 -181.9 -179.9 -178.2 -181.5 -177.5 -179.9 -183.1 -181.5 -181.8 -177.4 -177.6 -174.5 -178.4 -183.8 -181.6 -186.4 -178.1 -177.3 -179.1 -183.6 -191.2 -181.7 -187.6 -186.1 -183.5 -185.0 -186.5 -187.5 -190.5 -224.7 -177.3 -189.2 -191.7 -188.0 -182.8 -187.8 -182.2 -241.9 -197.6 -188.3 -181.7 -195.5 -184.4 -190.9 -187.4 -195.0 -190.0 -180.5 -179.1 -180.3 -195.0 -176.7 -191.8 -200.2 -180.3 -180.6 -186.1 -178.2 -182.5 -183.2 -178.9 -177.6 -185.6 -203.5 -179.7 -179.6 -190.8 -187.4 -184.7 -185.1 -195.1 -191.9 -181.1 -183.1 -177.1 -177.9 -178.5 -178.8 -186.0 -189.9 -184.7 -190.4 -192.9 -178.6 -176.1 -189.2 -186.1 -178.6 -186.9 -181.5 -181.5 -181.2 -178.1 -181.8 -187.6 -183.3 -188.5 -179.6 -183.5 -187.9 -179.6 -192.4 -182.6 -192.1 -255.4 -266.2 -191.5 -194.8 -179.7 -190.8 -182.8 -182.3 -186.7 -186.4 -178.1 -182.5 -175.0 -187.7 -199.4 -182.1 -180.5 -182.9 -175.9 -219.6 -207.0 -196.5 -190.7 -199.1 -185.4 -174.5 -180.5 -182.7 -181.8 -189.2 -181.0 -198.2 -191.9 -185.3 -182.9 -188.5 -178.7 -179.2 -188.7 -188.5 -178.2 -197.6 -178.3 -192.7 -181.9 -191.2 -181.7 -176.1 -196.5 -187.7 -190.5 -187.8 -182.9 -189.9 -192.3 -177.4 -184.7 -178.3 -185.8 -182.0 -180.1 -183.1 -182.0 -176.1 -185.2 -196.0 -185.5 -179.1 -198.1 -197.5 -182.0 -177.0 -178.3 -202.9 -177.0 -180.6 -181.6 -191.6 -179.6 -180.9 -183.7 -188.4 -182.6 -185.7 -191.5 -178.6 -188.4 -184.0 -183.8 -189.3 -185.2 -192.9 -195.4 -197.1 -190.4 -186.5 -196.0 -189.8 -191.9 -187.3 -185.7 -198.0 -175.8 -183.7 -176.0 -179.9 -183.1 -186.7 -177.9 -179.2 -181.7 -184.9 -181.6 -178.5 -176.5 -176.7 -178.4 -184.7 -181.3 -182.3 -182.8 -182.6 -190.2 -177.0 -187.9 -188.1 -186.4 -187.8 -181.3 -187.7 -191.8 -182.5 -182.0 -180.1 -185.8 -177.8 -192.5 -185.2 -179.7 -179.3 -191.0 -181.3 -192.9 -180.3 -194.5 -187.6 -184.3 -194.7 -182.7 -177.7 -181.2 -177.2 -184.0 -181.8 -188.5 -187.8 -184.7 -181.7 -184.6 -177.4 -193.0 -178.7 -176.5 -176.9 -180.9 -180.8 -187.8 -179.8 -175.2 -177.5 -180.5 -186.6 -177.0 -177.8 -177.8 -182.5 -180.0 -182.4 -188.6 -192.5 -177.5 -179.8 -178.8 -178.9 -182.0 -180.6 -184.5 -179.9 -175.4 -183.1 -177.8 -177.2 -191.7 -184.6 -183.1 -175.6 -200.6 -221.5 -177.2 -177.6 -184.0 -183.4 -199.2 -184.6 -186.1 -180.3 -188.1 -184.1 -185.9 -178.0 -183.7 -186.7 -186.1 -177.8 -183.5 -178.0 -177.0 -185.6 -187.0 -178.9 -178.9 -200.5 -180.2 -181.6 -187.8 -179.8 -182.0 -184.3 -176.3 -182.8 -184.3 -181.9 -185.3 -189.2 -177.3 -183.6 -186.7 -184.0 -243.9 -175.9 -184.3 -176.0 -179.6 -178.5 -182.3 -189.7 -179.6 -190.3 -188.8 -175.2 -179.8 -181.0 -175.6 -175.3 -187.5 -175.3 -186.8 -176.6 -177.3 -175.7 -178.5 -178.8 -178.5 -178.9 -183.7 -182.2 -182.3 -178.9 -182.0 -178.6 -184.2 -178.8 -176.7 -176.9 -176.2 -181.1 -177.9 -177.2 -178.6 -194.8 -185.4 -188.3 -178.9 -187.1 -184.3 -184.2 -190.3 -193.8 -185.0 -181.0 -181.4 -181.0 -191.8 -177.4 -178.6 -179.6 -180.2 -179.0 -187.4 -177.1 -182.7 -181.9 -177.9 -184.8 -195.1 -181.2 -182.1 -187.4 -186.8 -184.7 -181.9 -188.7 -191.8 -184.7 -185.5 -183.5 -180.8 -206.1 -179.1 -194.3 -178.0 -177.4 -181.0 -181.7 -190.6 -189.3 -176.3 -183.5 -178.9 -179.4 -187.3 -182.5 -181.7 -183.3 -188.9 -181.3 -195.6 -180.4 -194.0 -182.6 -176.6 -190.8 -176.3 -186.1 -185.1 -181.5 -179.2 -178.3 -179.6 -181.5 -181.0 -183.2 -182.6 -202.6 -183.7 -188.2 -200.6 -177.9 -184.2 -192.0 -180.9 -177.3 -177.2 -188.1 -184.2 -199.4 -185.3 -189.7 -199.8 -176.6 -189.2 -186.3 -182.8 -180.0 -190.8 -188.5 -194.6 -184.8 -202.7 -189.8 -183.2 -206.2 -175.3 -202.1 -193.5 -210.1 -200.5 -194.8 -190.0 -189.3 -182.5 -183.3 -187.1 -186.1 -208.1 -191.4 -207.5 -188.6 -176.7 -190.8 -189.1 -177.2 -189.3 -177.3 -196.2 -195.3 -188.0 -194.1 -181.3 -177.8 -186.2 -184.4 -182.0 -182.5 -187.1 -179.8 -177.4 -184.0 -180.5 -182.9 -176.4 -175.9 -176.8 -182.8 -208.0 -196.3 -183.4 -178.5 -189.7 -183.3 -182.5 -182.7 -182.5 -195.7 -183.8 -182.6 -190.0 -191.0 -191.7 -177.2 -184.1 -202.9 -189.8 -185.0 -183.3 -194.2 -182.8 -178.9 -184.9 -189.1 -192.8 -181.1 -190.5 -205.2 -179.1 -191.3 -186.8 -188.9 -178.8 -188.0 -184.1 -183.1 -182.1 -181.9 -191.6 -183.4 -189.9 -180.2 -186.6 -180.3 -182.7 -184.8 -178.4 -180.3 -193.7 -181.5 -186.6 -179.1 -184.3 -192.1 -189.5 -182.2 -296.4 -194.8 -179.0 -183.4 -194.3 -199.5 -182.7 -181.0 -181.8 -186.9 -186.4 -188.3 -179.2 -190.1 -184.9 -187.8 -186.3 -183.4 -183.1 -191.3 -188.5 -188.5 -187.9 -188.7 -175.3 -178.4 -197.5 -185.3 -201.3 -190.9 -210.1 -179.0 -176.3 -179.4 -195.0 -179.0 -176.4 -188.5 -180.5 -179.5 -179.4 -177.5 -185.2 -179.9 -178.3 -183.8 -193.9 -183.1 -187.7 -192.7 -181.3 -184.1 -182.5 -178.2 -184.0 -195.4 -179.7 -191.7 -183.7 -185.6 -188.4 -195.0 -184.8 -181.8 -186.2 -177.4 -189.8 -192.1 -192.9 -187.5 -191.5 -189.1 -195.7 -188.0 -192.7 -190.1 -190.1 -196.3 -192.4 -193.1 -178.9 -181.9 -179.2 -188.4 -179.2 -187.5 -179.7 -185.3 -177.2 -180.5 -182.2 -203.8 -186.1 -181.7 -180.8 -187.9 -177.4 -189.5 -189.3 -176.5 -179.2 -190.5 -180.0 -177.1 -183.7 -188.8 -180.6 -220.6 -190.9 -197.9 -182.8 -183.0 -177.9 -182.2 -182.4 -201.5 -181.1 -177.8 -189.6 -193.4 -180.3 -180.2 -175.3 -177.8 -178.3 -178.8 -190.7 -181.8 -185.1 -190.2 -179.1 -179.9 -179.8 -180.6 -181.6 -180.8 -184.6 -184.9 -181.7 -176.3 -182.2 -186.9 -227.1 -184.9 -184.5 -177.5 -180.2 -187.5 -186.1 -183.8 -177.4 -184.1 -188.1 -180.4 -197.4 -209.6 -198.3 -179.5 -183.9 -183.5 -181.8 -178.9 -195.5 -184.7 -191.3 -193.5 -196.8 -197.0 -184.2 -181.9 -187.5 -188.7 -177.7 -186.7 -191.6 -192.8 -194.8 -193.6 -194.7 -187.6 -197.2 -187.5 -176.0 -194.4 -199.9 -188.2 -184.5 -183.2 -186.0 -183.6 -210.5 -183.7 -190.4 -188.6 -179.8 -183.9 -210.2 -194.0 -190.8 -188.3 -186.2 -178.0 -178.3 -194.4 -184.5 -182.3 -179.1 -183.4 -182.9 -185.1 -180.6 -182.1 -189.4 -181.6 -180.5 -190.4 -182.1 -204.0 -192.7 -180.4 -190.7 -179.5 -179.2 -181.5 -186.1 -195.1 -189.7 -189.9 -185.9 -206.2 -187.5 -178.5 -206.2 -208.5 -187.4 -182.0 -192.9 -193.0 -196.5 -190.1 -179.7 -205.9 -187.7 -211.5 -177.5 -185.1 -205.3 -178.9 -179.6 -178.8 -185.9 -180.1 -179.0 -178.2 -181.9 -182.9 -191.5 -194.8 -184.9 -177.9 -186.0 -178.7 -175.2 -178.1 -183.9 -176.2 -196.3 -195.0 -214.4 -177.2 -175.2 -181.4 -191.4 -189.0 -179.6 -181.8 -177.8 -175.9 -176.1 -183.8 -182.1 -178.4 -182.1 -180.6 -177.4 -178.9 -178.7 -182.0 -176.5 -182.1 -189.2 -188.3 -184.6 -177.6 -184.6 -183.6 -182.6 -181.5 -198.4 -179.6 -179.3 -185.1 -189.8 -183.5 -180.9 -175.7 -182.6 -179.1 -181.3 -181.4 -189.8 -183.7 -185.8 -185.9 -178.1 -182.3 -196.3 -220.0 -199.4 -191.3 -186.7 -181.7 -180.7 -180.9 -176.2 -185.3 -180.3 -182.5 -177.5 -182.4 -184.8 -191.3 -185.5 -184.4 -193.8 -186.5 -178.9 -180.6 -182.7 -180.1 -184.8 -179.7 -187.8 -183.7 -190.9 -192.5 -205.5 -193.1 -180.7 -186.4 -179.3 -194.2 -187.8 -190.6 -178.8 -176.7 -181.2 -187.6 -191.3 -182.4 -204.9 -191.0 -193.8 -194.0 -198.4 -181.7 -186.5 -186.4 -182.5 -182.2 -179.0 -180.6 -180.0 -181.1 -178.6 -178.6 -183.3 -189.1 -179.9 -190.2 -187.3 -185.3 -185.0 -185.9 -189.3 -182.6 -183.5 -190.8 -183.4 -185.2 -197.1 -187.5 -182.2 -180.4 -181.3 -178.8 -182.5 -183.2 -174.8 -180.4 -200.9 -181.5 -185.5 -176.6 -179.0 -187.4 -173.8 -192.6 -179.3 -188.7 -198.9 -177.8 -185.5 -177.1 -213.1 -185.7 -189.7 -186.6 -189.2 -188.1 -184.0 -184.5 -178.7 -183.9 -186.3 -199.0 -188.2 -191.9 -181.6 -177.4 -183.8 -179.2 -182.7 -182.1 -178.2 -187.3 -189.0 -188.1 -190.8 -184.1 -188.0 -178.9 -195.8 -179.3 -204.6 -183.3 -178.8 -178.8 -176.9 -179.9 -186.0 -181.6 -199.5 -179.6 -189.0 -204.2 -189.7 -181.2 -184.5 -193.4 -183.7 -180.2 -186.2 -191.0 -195.1 -179.9 -182.6 -188.7 -184.5 -178.9 -194.1 -191.5 -179.9 -198.8 -183.4 -212.7 -179.0 -181.8 -176.5 -181.9 -179.7 -186.2 -187.0 -181.6 -184.9 -199.7 -185.4 -186.1 -179.3 -200.6 -187.7 -195.2 -185.5 -182.2 -189.4 -184.6 -177.9 -182.5 -182.9 -191.4 -192.5 -186.2 -178.4 -197.8 -175.7 -183.2 -187.5 -192.9 -175.8 -195.1 -185.7 -188.6 -191.6 -177.0 -181.8 -188.2 -202.4 -183.8 -184.5 -198.6 -186.4 -180.7 -188.6 -181.4 -178.9 -186.5 -185.5 -187.7 -187.7 -179.1 -184.2 -185.1 -178.0 -182.0 -197.0 -194.9 -193.6 -177.0 -186.6 -179.8 -186.1 -177.7 -182.1 -181.3 -178.0 -184.8 -208.3 -193.1 -187.2 -207.7 -188.2 -186.1 -178.1 -193.3 -182.1 -199.8 -182.7 -196.4 -197.9 -178.8 -191.4 -180.9 -180.5 -184.6 -177.2 -182.4 -183.7 -178.2 -187.1 -178.5 -181.3 -190.5 -179.0 -181.0 -178.0 -185.5 -179.1 -184.9 -184.7 -177.7 -176.7 -183.5 -196.3 -184.2 -190.0 -189.4 -186.0 -181.7 -186.0 -188.7 -187.5 -184.6 -176.3 -177.4 -185.9 -183.4 -179.4 -175.8 -186.1 -178.8 -179.0 -181.6 -175.2 -177.4 -176.8 -177.9 -197.6 -184.9 -176.0 -177.6 -178.4 -184.6 -178.1 -183.2 -180.2 -191.3 -180.0 -176.2 -180.3 -181.8 -187.4 -181.7 -177.1 -182.9 -190.6 -183.9 -177.9 -187.4 -174.9 -186.4 -192.0 -190.2 -198.4 -183.6 -206.3 -184.2 -181.0 -195.6 -277.2 -189.9 -187.0 -196.6 -180.6 -183.0 -208.8 -193.1 -188.9 -186.4 -179.9 -181.7 -185.2 -189.5 -188.0 -181.2 -182.5 -183.5 -190.3 -179.3 -182.3 -179.5 -184.2 -193.3 -178.5 -178.5 -182.3 -184.7 -181.9 -185.0 -181.6 -180.0 -202.6 -178.9 -176.4 -185.0 -190.3 -179.4 -182.9 -194.1 -185.2 -198.6 -177.6 -181.1 -179.8 -183.1 -187.7 -187.5 -185.9 -191.2 -183.1 -184.6 -193.0 -197.6 -183.3 -184.4 -181.6 -184.9 -178.0 -177.4 -181.0 -178.9 -180.4 -181.4 -188.0 -178.2 -181.2 -179.0 -188.1 -176.0 -176.4 -179.6 -179.1 -182.2 -185.6 -176.2 -180.0 -195.4 -177.4 -185.2 -177.5 -181.3 -187.8 -176.7 -200.8 -179.8 -183.8 -179.9 -190.4 -180.3 -178.5 -182.7 -180.3 -179.1 -178.8 -184.3 -176.7 -181.8 -179.9 -175.7 -181.6 -184.5 -183.3 -214.3 -175.7 -188.8 -180.1 -179.9 -182.8 -175.0 -177.4 -217.5 -183.7 -178.3 -184.0 -182.2 -175.4 -184.0 -181.2 -184.5 -174.6 -176.0 -180.1 -173.6 -190.4 -177.5 -181.3 -176.1 -181.5 -199.2 -176.2 -186.0 -178.6 -186.9 -187.1 -172.8 -175.5 -182.1 -175.9 -200.4 -193.1 -178.0 -177.1 -180.6 -182.2 -179.0 -175.8 -182.0 -188.0 -180.1 -207.1 -187.0 -180.6 -183.8 -192.9 -175.7 -193.6 -178.3 -182.2 -179.9 -177.2 -181.3 -177.0 -201.1 -176.2 -175.5 -183.1 -181.3 -176.0 -187.7 -185.7 -179.2 -183.4 -184.8 -176.3 -179.3 -175.2 -185.4 -181.2 -177.2 -179.9 -175.1 -175.7 -193.8 -179.7 -184.6 -181.2 -187.8 -184.9 -182.3 -184.9 -181.7 -186.0 -187.0 -178.5 -174.9 -180.7 -188.9 -181.4 -181.3 -176.2 -182.0 -183.4 -181.3 -181.3 -175.0 -179.7 -186.6 -183.7 -185.1 -180.8 -179.6 -180.6 -193.6 -187.6 -181.0 -176.3 -191.0 -177.5 -186.9 -173.8 -184.1 -178.1 -183.2 -180.2 -194.2 -175.8 -183.6 -175.4 -176.6 -183.7 -177.9 -176.4 -180.8 -179.9 -177.9 -183.0 -176.9 -181.3 -182.2 -182.3 -183.8 -181.1 -180.6 -189.9 -185.6 -184.5 -185.3 -175.3 -192.4 -195.5 -188.2 -180.3 -196.3 -184.1 -178.7 -179.7 -187.0 -177.1 -180.7 -177.5 -177.1 -180.8 -182.0 -177.0 -177.0 -193.1 -194.6 -190.0 -183.5 -180.5 -178.4 -177.4 -178.7 -184.6 -189.6 -188.1 -186.1 -184.2 -178.9 -176.7 -195.8 -178.1 -187.6 -175.4 -180.3 -185.3 -189.0 -177.2 -188.9 -179.0 -184.0 -179.1 -187.3 -199.7 -178.2 -179.1 -175.8 -179.8 -178.8 -196.3 -185.0 -196.3 -181.1 -185.5 -175.8 -189.2 -179.4 -192.0 -182.6 -177.9 -181.1 -179.6 -184.2 -194.6 -185.9 -181.4 -176.5 -178.3 -176.3 -179.1 -175.3 -180.5 -186.7 -177.5 -192.3 -187.7 -178.4 -189.4 -180.4 -180.5 -189.9 -183.8 -190.3 -195.5 -185.6 -177.2 -177.7 -178.7 -189.9 -183.8 -193.1 -185.2 -180.5 -180.5 -191.6 -175.0 -176.6 -178.6 -188.8 -180.7 -185.5 -181.2 -199.5 -193.2 -193.8 -185.8 -182.0 -178.5 -188.7 -190.1 -178.7 -181.5 -180.9 -186.6 -189.8 -194.4 -180.1 -193.0 -178.2 -183.2 -182.6 -177.8 -212.2 -177.5 -178.5 -181.9 -185.8 -177.2 -182.9 -176.7 -175.1 -180.4 -186.0 -179.1 -179.5 -177.2 -182.1 -177.8 -180.1 -180.1 -177.9 -183.6 -189.2 -193.2 -179.6 -176.9 -181.3 -178.4 -177.4 -189.2 -182.1 -195.2 -193.0 -184.5 -180.4 -184.1 -176.2 -180.1 -179.0 -174.8 -181.1 -190.0 -179.9 -192.2 -204.9 -179.2 -180.5 -174.7 -181.6 -181.5 -185.1 -176.7 -184.9 -191.9 -182.2 -182.7 -210.5 -186.1 -181.1 -179.3 -186.4 -176.0 -177.4 -180.9 -187.0 -192.2 -182.9 -182.2 -184.0 -180.3 -177.4 -178.7 -176.8 -176.4 -176.1 -182.0 -178.8 -175.2 -187.6 -184.9 -184.3 -188.7 -178.3 -190.9 -186.3 -175.2 -185.8 -175.6 -184.8 -181.1 -176.8 -179.0 -179.2 -196.5 -175.0 -182.6 -194.4 -173.7 -180.0 -178.3 -181.1 -179.5 -177.6 -185.1 -183.2 -188.6 -186.8 -182.5 -176.4 -175.1 -176.9 -182.4 -180.1 -181.7 -182.8 -184.1 -175.7 -178.7 -177.1 -178.3 -177.3 -176.7 -179.8 -176.8 -177.2 -200.5 -175.7 -181.1 -174.5 -179.3 -183.1 -178.4 -189.2 -186.0 -177.4 -178.3 -187.1 -181.0 -183.3 -191.4 -182.9 -182.6 -199.2 -181.4 -180.5 -180.4 -176.7 -184.4 -189.0 -188.1 -197.0 -181.2 -176.1 -181.0 -180.5 -176.5 -214.9 -178.3 -178.7 -181.4 -180.9 -178.0 -185.8 -182.5 -181.8 -177.4 -186.7 -183.2 -183.2 -183.1 -173.9 -181.1 -179.1 -180.3 -177.7 -181.5 -176.5 -177.1 -189.6 -191.5 -183.2 -180.0 -180.9 -183.3 -188.3 -178.4 -185.4 -176.1 -183.2 -181.1 -180.3 -176.4 -177.5 -186.8 -176.3 -338.9 -184.9 -177.0 -187.1 -175.8 -180.0 -182.5 -184.9 -175.2 -179.6 -176.9 -178.7 -177.5 -178.3 -178.9 -180.7 -182.6 -179.3 -177.0 -180.5 -179.2 -177.2 -188.0 -194.8 -183.6 -177.3 -179.1 -185.3 -177.5 -187.6 -180.9 -188.0 -174.8 -183.6 -183.0 -182.9 -178.1 -182.0 -185.9 -176.5 -182.1 -188.5 -179.9 -176.0 -184.3 -185.9 -179.2 -184.3 -181.3 -186.3 -186.7 -177.5 -188.9 -178.8 -211.3 -188.0 -178.5 -192.6 -176.4 -187.1 -189.5 -195.7 -188.5 -185.1 -182.5 -176.6 -182.5 -187.3 -180.5 -191.9 -178.3 -177.1 -188.3 -181.0 -178.0 -187.1 -175.1 -182.3 -177.4 -177.6 -181.2 -179.2 -183.8 -183.2 -173.3 -177.6 -178.6 -179.4 -180.5 -183.9 -176.3 -178.4 -178.9 -175.9 -179.2 -175.4 -183.5 -188.9 -176.5 -185.8 -179.7 -196.8 -185.9 -178.4 -176.4 -177.6 -176.0 -177.9 -181.7 -176.2 -180.6 -179.9 -186.0 -177.2 -178.9 -179.1 -186.6 -176.0 -194.6 -179.2 -181.5 -176.2 -177.2 -179.3 -181.3 -179.2 -181.7 -177.5 -186.6 -179.5 -177.4 -179.4 -177.9 -181.9 -181.3 -177.4 -176.0 -177.8 -185.2 -180.8 -181.3 -182.1 -178.2 -179.5 -185.6 -179.5 -182.5 -186.1 -188.7 -178.7 -186.8 -179.2 -197.7 -180.8 -181.4 -178.1 -207.1 -182.7 -185.5 -186.1 -180.1 -176.1 -177.6 -174.9 -176.1 -180.6 -184.5 -179.2 -186.1 -180.5 -179.5 -179.3 -182.2 -181.8 -184.6 -180.0 -177.1 -176.7 -177.6 -180.8 -176.5 -177.3 -176.8 -176.4 -188.7 -187.6 -178.5 -178.0 -179.3 -181.4 -183.2 -193.8 -178.3 -181.2 -180.4 -183.5 -179.8 -177.4 -183.2 -183.3 -176.6 -176.2 -216.9 -177.8 -177.0 -178.0 -175.3 -189.4 -182.6 -182.9 -183.6 -180.4 -177.2 -176.0 -177.9 -175.1 -182.1 -178.3 -178.5 -186.2 -177.7 -178.0 -183.3 -180.4 -197.6 -181.7 -179.9 -184.0 -194.8 -184.8 -189.4 -191.8 -176.6 -186.2 -180.3 -177.7 -197.0 -187.0 -188.1 -190.1 -176.8 -179.3 -185.4 -174.7 -189.6 -184.2 -178.0 -180.4 -183.4 -179.5 -177.7 -178.7 -186.9 -183.7 -177.2 -173.6 -184.7 -180.4 -183.1 -175.6 -179.6 -184.8 -185.6 -176.2 -177.7 -180.0 -174.7 -183.1 -181.6 -178.0 -178.8 -185.4 -181.2 -178.0 -188.7 -177.1 -189.3 -177.6 -180.6 -181.6 -175.9 -180.7 -179.1 -182.4 -186.7 -175.8 -185.1 -176.7 -180.3 -195.7 -191.3 -191.1 -181.3 -180.5 -179.3 -184.3 -177.1 -182.4 -179.4 -188.8 -174.5 -177.2 -178.4 -179.8 -183.3 -175.4 -184.1 -176.8 -182.4 -177.8 -178.7 -178.6 -189.6 -182.0 -191.2 -179.8 -179.3 -178.6 -183.0 -188.8 -205.3 -180.1 -190.6 -184.4 -179.9 -178.6 -174.7 -180.6 -193.3 -175.3 -175.5 -193.9 -180.4 -177.2 -175.6 -177.0 -182.3 -183.5 -181.9 -179.6 -182.8 -180.9 -180.6 -183.7 -185.0 -176.7 -190.5 -176.2 -179.0 -178.8 -180.0 -181.5 -174.3 -177.3 -179.2 -178.3 -184.7 -174.2 -177.3 -178.0 -178.9 -182.9 -189.8 -183.3 -183.0 -182.5 -176.3 -176.8 -177.5 -176.2 -183.1 -175.4 -175.0 -182.5 -174.9 -185.8 -181.4 -178.4 -183.8 -178.0 -265.0 -178.5 -185.0 -177.4 -179.2 -175.8 -183.0 -184.5 -195.3 -178.5 -178.2 -179.7 -175.0 -187.5 -182.7 -180.3 -181.0 -177.5 -181.5 -179.9 -179.0 -180.0 -182.6 -178.5 -179.6 -181.4 -188.0 -188.2 -179.1 -180.8 -178.5 -181.3 -179.9 -182.0 -181.8 -181.3 -186.6 -197.8 -205.8 -188.2 -194.9 -182.2 -184.6 -188.9 -189.4 -183.4 -179.2 -182.6 -184.6 -183.6 -184.3 -182.5 -181.1 -181.6 -178.9 -179.7 -176.3 -179.4 -180.2 -178.4 -179.6 -190.1 -178.5 -174.4 -177.3 -176.1 -175.3 -175.0 -178.9 -175.1 -181.3 -175.0 -176.0 -192.2 -189.2 -182.4 -179.2 -173.4 -177.9 -178.4 -175.5 -175.9 -199.0 -196.6 -181.7 -181.2 -177.6 -174.7 -174.3 -181.3 -178.9 -203.2 -176.3 -175.8 -192.3 -180.8 -184.8 -179.9 -182.4 -180.0 -174.3 -187.2 -181.4 -176.0 -174.4 -182.4 -186.8 -191.1 -177.1 -178.2 -176.8 -182.6 -184.6 -181.5 -185.4 -178.9 -176.6 -179.6 -175.1 -179.9 -176.9 -176.7 -186.2 -192.9 -183.5 -182.4 -175.5 -176.9 -180.6 -185.7 -174.2 -174.2 -178.9 -178.8 -179.2 -194.9 -177.5 -174.0 -179.0 -180.7 -174.0 -180.0 -178.3 -179.8 -180.0 -175.6 -174.9 -180.9 -177.3 -212.6 -196.0 -183.1 -186.5 -178.4 -185.9 -185.5 -176.8 -178.7 -174.0 -176.6 -179.0 -182.3 -176.6 -185.0 -175.7 -178.5 -176.4 -176.3 -186.3 -222.5 -185.7 -177.1 -183.6 -176.9 -184.0 -175.7 -174.4 -184.2 -269.8 -182.5 -174.6 -178.5 -176.1 -178.9 -177.9 -181.9 -176.8 -174.2 -181.6 -191.2 -179.1 -175.3 -182.2 -180.1 -175.2 -182.3 -175.6 -177.1 -175.1 -174.7 -188.2 -176.9 -183.6 -175.9 -175.5 -174.7 -182.4 -181.2 -179.5 -190.3 -184.8 -237.1 -178.3 -178.7 -184.1 -174.5 -178.3 -178.6 -181.8 -182.2 -190.2 -179.9 -181.0 -180.3 -177.2 -179.2 -179.2 -178.2 -183.0 -177.7 -180.1 -182.6 -196.6 -178.9 -177.0 -176.1 -178.3 -182.9 -176.5 -209.4 -181.1 -199.5 -186.3 -177.6 -182.7 -185.4 -180.2 -186.2 -187.4 -176.4 -182.8 -221.0 -179.0 -178.9 -178.4 -186.8 -174.1 -174.9 -176.8 -190.0 -178.9 -182.4 -178.7 -177.6 -179.4 -173.6 -178.1 -179.8 -177.8 -177.5 -187.5 -209.5 -178.0 -177.2 -179.3 -179.8 -179.8 -174.4 -177.1 -180.2 -182.5 -181.1 -184.7 -179.6 -193.0 -182.7 -181.6 -177.7 -178.2 -181.6 -186.6 -177.2 -178.1 -189.3 -174.3 -180.2 -186.2 -189.8 -185.9 -176.8 -178.8 -175.1 -175.5 -179.1 -180.9 -186.1 -187.0 -186.2 -187.6 -187.5 -197.8 -180.4 -196.7 -176.5 -177.6 -176.2 -180.8 -175.9 -182.8 -178.8 -184.6 -179.5 -175.6 -187.5 -175.7 -201.6 -188.2 -183.4 -184.2 -178.7 -177.0 -174.9 -181.9 -177.6 -177.7 -179.6 -176.0 -178.3 -181.5 -177.5 -184.7 -183.9 -180.9 -178.9 -177.8 -176.6 -188.4 -191.0 -189.6 -178.1 -177.9 -186.1 -178.7 -184.3 -176.5 -179.6 -174.1 -184.4 -176.8 -182.3 -179.5 -188.8 -180.2 -176.1 -198.4 -178.4 -188.6 -191.0 -180.4 -179.5 -176.0 -188.1 -189.6 -192.6 -177.0 -189.1 -177.5 -178.8 -186.8 -178.6 -180.5 -184.0 -178.7 -179.0 -176.2 -176.7 -185.2 -192.3 -178.0 -175.7 -181.0 -183.0 -175.7 -174.6 -176.7 -177.8 -179.0 -177.4 -176.7 -182.5 -194.0 -181.4 -178.7 -176.2 -176.7 -204.2 -178.3 -190.6 -188.5 -177.5 -180.6 -178.1 -175.2 -276.8 -353.6 -297.8 -235.1 -211.7 -213.4 -213.5 -191.5 -178.8 -186.2 -175.4 -178.2 -184.5 -179.9 -182.0 -179.3 -178.6 -192.5 -177.7 -179.2 -194.9 -183.1 -178.6 -179.9 -192.5 -184.1 -186.6 -181.2 -175.4 -197.2 -179.6 -184.6 -197.6 -180.6 -189.6 -175.3 -185.6 -174.5 -178.9 -174.2 -179.6 -173.9 -182.5 -185.6 -177.4 -191.4 -183.8 -177.0 -181.2 -176.3 -177.3 -173.7 -177.5 -178.9 -178.2 -177.3 -177.7 -187.8 -181.6 -178.4 -176.4 -180.8 -178.5 -189.5 -186.0 -188.4 -182.2 -184.0 -176.5 -179.5 -185.3 -173.8 -190.0 -180.2 -189.1 -184.9 -175.8 -182.2 -177.9 -176.4 -184.1 -179.5 -181.8 -175.7 -179.7 -178.7 -185.9 -180.5 -180.9 -175.5 -176.1 -174.4 -175.1 -195.2 -174.9 -190.5 -183.8 -188.7 -182.5 -179.5 -177.0 -174.9 -185.6 -180.8 -192.8 -185.2 -184.0 -177.7 -191.7 -185.3 -185.4 -186.6 -182.9 -181.1 -191.2 -183.0 -176.6 -187.7 -181.9 -179.5 -178.7 -176.9 -178.5 -182.1 -175.4 -175.9 -183.8 -180.6 -191.1 -177.0 -184.6 -188.7 -176.0 -181.4 -188.2 -181.1 -180.0 -178.9 -182.1 -179.6 -179.5 -174.5 -177.6 -179.9 -175.3 -185.2 -175.4 -185.1 -184.9 -182.0 -178.4 -177.0 -182.3 -193.8 -181.6 -197.4 -180.4 -180.9 -182.0 -181.0 -185.8 -178.5 -180.5 -182.3 -175.7 -176.5 -182.8 -176.8 -178.3 -179.5 -181.8 -175.1 -180.2 -179.6 -176.7 -174.6 -180.5 -179.7 -178.9 -177.1 -184.2 -178.4 -175.0 -183.7 -178.3 -179.1 -175.3 -187.5 -189.2 -176.7 -205.6 -179.6 -179.6 -179.1 -182.1 -178.6 -182.2 -181.6 -181.9 -188.8 -184.7 -185.3 -182.5 -174.2 -176.5 -190.1 -180.6 -182.7 -182.2 -179.5 -179.0 -184.4 -175.4 -178.2 -174.6 -179.0 -188.4 -175.9 -173.8 -180.2 -187.3 -186.3 -176.3 -174.9 -178.6 -178.2 -177.0 -180.0 -177.2 -173.5 -195.4 -180.5 -181.6 -177.2 -176.7 -175.3 -174.8 -179.7 -175.0 -176.4 -181.8 -183.0 -180.0 -177.0 -185.8 -183.2 -181.0 -176.8 -177.9 -186.1 -182.5 -174.4 -177.1 -176.7 -176.3 -180.3 -178.9 -178.3 -175.8 -179.9 -190.6 -182.8 -183.4 -177.9 -177.7 -180.0 -202.0 -184.5 -179.5 -181.5 -174.8 -194.2 -185.8 -177.0 -183.9 -177.6 -202.4 -179.9 -175.4 -174.8 -176.7 -177.9 -176.6 -176.5 -181.2 -181.3 -177.4 -179.3 -177.8 -176.2 -197.2 -180.9 -178.2 -184.6 -184.7 -191.0 -182.9 -179.9 -180.3 -177.4 -182.1 -181.9 -182.2 -174.9 -193.4 -175.1 -203.2 -176.0 -180.3 -180.0 -186.3 -174.8 -177.9 -196.1 -177.6 -183.5 -176.2 -187.6 -178.5 -180.6 -178.2 -180.7 -177.6 -176.6 -173.5 -178.7 -175.0 -179.0 -175.5 -174.2 -178.2 -176.6 -176.3 -179.4 -178.6 -175.2 -175.9 -175.0 -179.5 -176.9 -184.0 -184.6 -179.9 -175.3 -176.2 -179.1 -182.8 -180.5 -173.4 -176.0 -198.9 -177.0 -189.7 -183.6 -179.5 -176.5 -175.5 -175.5 -176.4 -182.9 -178.7 -177.5 -180.6 -175.0 -178.9 -177.7 -178.0 -178.6 -176.0 -177.6 -180.8 -179.6 -184.3 -190.2 -177.7 -178.1 -175.0 -178.6 -179.6 -185.1 -193.7 -179.8 -179.3 -178.6 -180.4 -174.9 -177.8 -187.4 -183.7 -181.6 -177.7 -185.4 -180.6 -178.5 -182.8 -179.9 -177.8 -178.0 -184.3 -191.0 -181.1 -197.9 -181.1 -197.8 -175.6 -176.9 -177.9 -187.4 -180.8 -180.6 -174.9 -180.8 -175.7 -176.4 -179.9 -178.3 -178.3 -178.4 -196.4 -177.3 -184.3 -177.3 -176.5 -181.0 -175.0 -179.2 -178.1 -183.3 -177.0 -175.2 -177.2 -173.5 -176.5 -177.0 -178.6 -181.3 -189.2 -186.4 -177.4 -181.7 -176.2 -194.1 -177.9 -186.6 -182.6 -176.6 -175.4 -250.3 -178.7 -183.0 -182.7 -183.1 -183.6 -178.8 -178.3 -179.1 -177.7 -177.9 -186.2 -195.4 -179.2 -183.3 -183.8 -186.3 -182.7 -178.9 -196.0 -177.1 -184.5 -188.3 -188.4 -181.5 -190.1 -179.0 -177.2 -189.1 -184.1 -184.2 -178.7 -187.4 -182.5 -189.8 -181.1 -186.0 -178.8 -178.0 -176.9 -180.6 -174.3 -180.4 -176.7 -175.5 -193.7 -189.7 -196.6 -178.9 -186.3 -182.5 -185.7 -175.7 -176.0 -194.1 -181.0 -178.6 -178.4 -186.8 -175.6 -185.4 -180.7 -184.7 -188.1 -180.4 -183.0 -178.4 -185.1 -181.8 -175.8 -178.9 -177.9 -177.9 -176.5 -290.3 -181.8 -180.8 -183.9 -190.8 -179.0 -183.7 -181.9 -177.5 -178.4 -179.4 -179.9 -174.2 -182.7 -182.9 -178.8 -179.2 -183.2 -181.8 -175.6 -179.0 -175.7 -178.1 -179.2 -183.8 -187.8 -187.3 -175.7 -175.0 -185.5 -175.3 -181.9 -176.7 -184.6 -185.8 -181.1 -186.6 -178.8 -183.4 -175.1 -178.4 -179.6 -176.7 -177.1 -176.5 -181.7 -199.1 -194.8 -176.5 -182.2 -189.9 -177.6 -179.3 -184.9 -178.1 -176.4 -184.6 -174.6 -188.6 -183.7 -178.1 -177.7 -186.1 -176.3 -180.9 -180.3 -181.0 -180.0 -180.0 -180.4 -174.8 -179.5 -176.5 -179.9 -175.6 -184.0 -176.4 -191.6 -178.4 -184.8 -186.7 -197.0 diff --git a/netem/maketable.c b/netem/maketable.c deleted file mode 100644 index ce09176..0000000 --- a/netem/maketable.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Experimental data distribution table generator - * Taken from the uncopyrighted NISTnet code. - * - * Rread in a series of "random" data values, either - * experimentally or generated from some probability distribution. - * From this, create the inverse distribution table used to approximate - * the distribution. - */ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <malloc.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> - - -double * -readdoubles(FILE *fp, int *number) -{ - struct stat info; - double *x; - int limit; - int n=0, i; - - fstat(fileno(fp), &info); - if (info.st_size > 0) { - limit = 2*info.st_size/sizeof(double); /* @@ approximate */ - } else { - limit = 10000; - } - - x = calloc(limit, sizeof(double)); - if (!x) { - perror("double alloc"); - exit(3); - } - - for (i=0; i<limit; ++i){ - fscanf(fp, "%lf", &x[i]); - if (feof(fp)) - break; - ++n; - } - *number = n; - return x; -} - -void -arraystats(double *x, int limit, double *mu, double *sigma, double *rho) -{ - int n=0, i; - double sumsquare=0.0, sum=0.0, top=0.0; - double sigma2=0.0; - - for (i=0; i<limit; ++i){ - sumsquare += x[i]*x[i]; - sum += x[i]; - ++n; - } - *mu = sum/(double)n; - *sigma = sqrt((sumsquare - (double)n*(*mu)*(*mu))/(double)(n-1)); - - for (i=1; i < n; ++i){ - top += ((double)x[i]- *mu)*((double)x[i-1]- *mu); - sigma2 += ((double)x[i-1] - *mu)*((double)x[i-1] - *mu); - - } - *rho = top/sigma2; -} - -/* Create a (normalized) distribution table from a set of observed - * values. The table is fixed to run from (as it happens) -4 to +4, - * with granularity .00002. - */ - -#define TABLESIZE 16384/4 -#define TABLEFACTOR 8192 -#ifndef MINSHORT -#define MINSHORT -32768 -#define MAXSHORT 32767 -#endif - -/* Since entries in the inverse are scaled by TABLEFACTOR, and can't be bigger - * than MAXSHORT, we don't bother looking at a larger domain than this: - */ -#define DISTTABLEDOMAIN ((MAXSHORT/TABLEFACTOR)+1) -#define DISTTABLEGRANULARITY 50000 -#define DISTTABLESIZE (DISTTABLEDOMAIN*DISTTABLEGRANULARITY*2) - -static int * -makedist(double *x, int limit, double mu, double sigma) -{ - int *table; - int i, index, first=DISTTABLESIZE, last=0; - double input; - - table = calloc(DISTTABLESIZE, sizeof(int)); - if (!table) { - perror("table alloc"); - exit(3); - } - - for (i=0; i < limit; ++i) { - /* Normalize value */ - input = (x[i]-mu)/sigma; - - index = (int)rint((input+DISTTABLEDOMAIN)*DISTTABLEGRANULARITY); - if (index < 0) index = 0; - if (index >= DISTTABLESIZE) index = DISTTABLESIZE-1; - ++table[index]; - if (index > last) - last = index +1; - if (index < first) - first = index; - } - return table; -} - -/* replace an array by its cumulative distribution */ -static void -cumulativedist(int *table, int limit, int *total) -{ - int accum=0; - - while (--limit >= 0) { - accum += *table; - *table++ = accum; - } - *total = accum; -} - -static short * -inverttable(int *table, int inversesize, int tablesize, int cumulative) -{ - int i, inverseindex, inversevalue; - short *inverse; - double findex, fvalue; - - inverse = (short *)malloc(inversesize*sizeof(short)); - for (i=0; i < inversesize; ++i) { - inverse[i] = MINSHORT; - } - for (i=0; i < tablesize; ++i) { - findex = ((double)i/(double)DISTTABLEGRANULARITY) - DISTTABLEDOMAIN; - fvalue = (double)table[i]/(double)cumulative; - inverseindex = (int)rint(fvalue*inversesize); - inversevalue = (int)rint(findex*TABLEFACTOR); - if (inversevalue <= MINSHORT) inversevalue = MINSHORT+1; - if (inversevalue > MAXSHORT) inversevalue = MAXSHORT; - inverse[inverseindex] = inversevalue; - } - return inverse; - -} - -/* Run simple linear interpolation over the table to fill in missing entries */ -static void -interpolatetable(short *table, int limit) -{ - int i, j, last, lasti = -1; - - last = MINSHORT; - for (i=0; i < limit; ++i) { - if (table[i] == MINSHORT) { - for (j=i; j < limit; ++j) - if (table[j] != MINSHORT) - break; - if (j < limit) { - table[i] = last + (i-lasti)*(table[j]-last)/(j-lasti); - } else { - table[i] = last + (i-lasti)*(MAXSHORT-last)/(limit-lasti); - } - } else { - last = table[i]; - lasti = i; - } - } -} - -static void -printtable(const short *table, int limit) -{ - int i; - - printf("# This is the distribution table for the experimental distribution.\n"); - - for (i=0 ; i < limit; ++i) { - printf("%d%c", table[i], - (i % 8) == 7 ? '\n' : ' '); - } -} - -int -main(int argc, char **argv) -{ - FILE *fp; - double *x; - double mu, sigma, rho; - int limit; - int *table; - short *inverse; - int total; - - if (argc > 1) { - if (!(fp = fopen(argv[1], "r"))) { - perror(argv[1]); - exit(1); - } - } else { - fp = stdin; - } - x = readdoubles(fp, &limit); - if (limit <= 0) { - fprintf(stderr, "Nothing much read!\n"); - exit(2); - } - arraystats(x, limit, &mu, &sigma, &rho); -#ifdef DEBUG - fprintf(stderr, "%d values, mu %10.4f, sigma %10.4f, rho %10.4f\n", - limit, mu, sigma, rho); -#endif - - table = makedist(x, limit, mu, sigma); - free((void *) x); - cumulativedist(table, DISTTABLESIZE, &total); - inverse = inverttable(table, TABLESIZE, DISTTABLESIZE, total); - interpolatetable(inverse, TABLESIZE); - printtable(inverse, TABLESIZE); - return 0; -} diff --git a/netem/normal.c b/netem/normal.c deleted file mode 100644 index dbdebb1..0000000 --- a/netem/normal.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Normal distribution table generator - * Taken from the uncopyrighted NISTnet code. - */ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include <limits.h> - -#include <linux/types.h> -#include <linux/pkt_sched.h> - -#define TABLESIZE 16384 -#define TABLEFACTOR NETEM_DIST_SCALE - -static double -normal(double x, double mu, double sigma) -{ - return .5 + .5*erf((x-mu)/(sqrt(2.0)*sigma)); -} - - -int -main(int argc, char **argv) -{ - int i, n; - double x; - double table[TABLESIZE+1]; - - for (x = -10.0; x < 10.05; x += .00005) { - i = rint(TABLESIZE * normal(x, 0.0, 1.0)); - table[i] = x; - } - - - printf("# This is the distribution table for the normal distribution.\n"); - for (i = n = 0; i < TABLESIZE; i += 4) { - int value = (int) rint(table[i]*TABLEFACTOR); - if (value < SHRT_MIN) value = SHRT_MIN; - if (value > SHRT_MAX) value = SHRT_MAX; - - printf(" %d", value); - if (++n == 8) { - putchar('\n'); - n = 0; - } - } - - return 0; -} diff --git a/netem/pareto.c b/netem/pareto.c deleted file mode 100644 index 8aa647b..0000000 --- a/netem/pareto.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Pareto distribution table generator - * Taken from the uncopyrighted NISTnet code. - */ -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <limits.h> - -#include <linux/types.h> -#include <linux/pkt_sched.h> - -static const double a=3.0; -#define TABLESIZE 16384 -#define TABLEFACTOR NETEM_DIST_SCALE - -int -main(int argc, char **argv) -{ - int i, n; - double dvalue; - - printf("# This is the distribution table for the pareto distribution.\n"); - - for (i = 65536, n = 0; i > 0; i -= 16) { - dvalue = (double)i/(double)65536; - dvalue = 1.0/pow(dvalue, 1.0/a); - dvalue -= 1.5; - dvalue *= (4.0/3.0)*(double)TABLEFACTOR; - if (dvalue > 32767) - dvalue = 32767; - - printf(" %d", (int)rint(dvalue)); - if (++n == 8) { - putchar('\n'); - n = 0; - } - } - - return 0; -} diff --git a/netem/paretonormal.c b/netem/paretonormal.c deleted file mode 100644 index ed75f28..0000000 --- a/netem/paretonormal.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Paretoormal distribution table generator - * - * This distribution is simply .25*normal + .75*pareto; a combination - * which seems to match experimentally observed distributions reasonably - * well, but is computationally easy to handle. - * The entries represent a scaled inverse of the cumulative distribution - * function. - * - * Taken from the uncopyrighted NISTnet code. - */ -#include <stdio.h> -#include <stdlib.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include <limits.h> -#include <malloc.h> - -#include <linux/types.h> -#include <linux/pkt_sched.h> - -#define TABLESIZE 16384 -#define TABLEFACTOR NETEM_DIST_SCALE - -static double -normal(double x, double mu, double sigma) -{ - return .5 + .5*erf((x-mu)/(sqrt(2.0)*sigma)); -} - -static const double a=3.0; - -static int -paretovalue(int i) -{ - double dvalue; - - i = 65536-4*i; - dvalue = (double)i/(double)65536; - dvalue = 1.0/pow(dvalue, 1.0/a); - dvalue -= 1.5; - dvalue *= (4.0/3.0)*(double)TABLEFACTOR; - if (dvalue > 32767) - dvalue = 32767; - return (int)rint(dvalue); -} - -int -main(int argc, char **argv) -{ - int i,n; - double x; - double table[TABLESIZE+1]; - - for (x = -10.0; x < 10.05; x += .00005) { - i = rint(TABLESIZE*normal(x, 0.0, 1.0)); - table[i] = x; - } - printf( -"# This is the distribution table for the paretonormal distribution.\n" - ); - - for (i = n = 0; i < TABLESIZE; i += 4) { - int normvalue, parvalue, value; - - normvalue = (int) rint(table[i]*TABLEFACTOR); - parvalue = paretovalue(i); - - value = (normvalue+3*parvalue)/4; - if (value < SHRT_MIN) value = SHRT_MIN; - if (value > SHRT_MAX) value = SHRT_MAX; - - printf(" %d", value); - if (++n == 8) { - putchar('\n'); - n = 0; - } - } - - return 0; -} diff --git a/tc-cbq-details.8 b/tc-cbq-details.8 deleted file mode 100644 index e47da62..0000000 --- a/tc-cbq-details.8 +++ /dev/null @@ -1,425 +0,0 @@ -.TH CBQ 8 "8 December 2001" "iproute2" "Linux" -.SH NAME -CBQ \- Class Based Queueing -.SH SYNOPSIS -.B tc qdisc ... dev -dev -.B ( parent -classid -.B | root) [ handle -major: -.B ] cbq avpkt -bytes -.B bandwidth -rate -.B [ cell -bytes -.B ] [ ewma -log -.B ] [ mpu -bytes -.B ] - -.B tc class ... dev -dev -.B parent -major:[minor] -.B [ classid -major:minor -.B ] cbq allot -bytes -.B [ bandwidth -rate -.B ] [ rate -rate -.B ] prio -priority -.B [ weight -weight -.B ] [ minburst -packets -.B ] [ maxburst -packets -.B ] [ ewma -log -.B ] [ cell -bytes -.B ] avpkt -bytes -.B [ mpu -bytes -.B ] [ bounded isolated ] [ split -handle -.B & defmap -defmap -.B ] [ estimator -interval timeconstant -.B ] - -.SH DESCRIPTION -Class Based Queueing is a classful qdisc that implements a rich -linksharing hierarchy of classes. It contains shaping elements as -well as prioritizing capabilities. Shaping is performed using link -idle time calculations based on the timing of dequeue events and -underlying link bandwidth. - -.SH SHAPING ALGORITHM -Shaping is done using link idle time calculations, and actions taken if -these calculations deviate from set limits. - -When shaping a 10mbit/s connection to 1mbit/s, the link will -be idle 90% of the time. If it isn't, it needs to be throttled so that it -IS idle 90% of the time. - -From the kernel's perspective, this is hard to measure, so CBQ instead -derives the idle time from the number of microseconds (in fact, jiffies) -that elapse between requests from the device driver for more data. Combined -with the knowledge of packet sizes, this is used to approximate how full or -empty the link is. - -This is rather circumspect and doesn't always arrive at proper -results. For example, what is the actual link speed of an interface -that is not really able to transmit the full 100mbit/s of data, -perhaps because of a badly implemented driver? A PCMCIA network card -will also never achieve 100mbit/s because of the way the bus is -designed - again, how do we calculate the idle time? - -The physical link bandwidth may be ill defined in case of not-quite-real -network devices like PPP over Ethernet or PPTP over TCP/IP. The effective -bandwidth in that case is probably determined by the efficiency of pipes -to userspace - which not defined. - -During operations, the effective idletime is measured using an -exponential weighted moving average (EWMA), which considers recent -packets to be exponentially more important than past ones. The Unix -loadaverage is calculated in the same way. - -The calculated idle time is subtracted from the EWMA measured one, -the resulting number is called 'avgidle'. A perfectly loaded link has -an avgidle of zero: packets arrive exactly at the calculated -interval. - -An overloaded link has a negative avgidle and if it gets too negative, -CBQ throttles and is then 'overlimit'. - -Conversely, an idle link might amass a huge avgidle, which would then -allow infinite bandwidths after a few hours of silence. To prevent -this, avgidle is capped at -.B maxidle. - -If overlimit, in theory, the CBQ could throttle itself for exactly the -amount of time that was calculated to pass between packets, and then -pass one packet, and throttle again. Due to timer resolution constraints, -this may not be feasible, see the -.B minburst -parameter below. - -.SH CLASSIFICATION -Within the one CBQ instance many classes may exist. Each of these classes -contains another qdisc, by default -.BR tc-pfifo (8). - -When enqueueing a packet, CBQ starts at the root and uses various methods to -determine which class should receive the data. If a verdict is reached, this -process is repeated for the recipient class which might have further -means of classifying traffic to its children, if any. - -CBQ has the following methods available to classify a packet to any child -classes. -.TP -(i) -.B skb->priority class encoding. -Can be set from userspace by an application with the -.B SO_PRIORITY -setsockopt. -The -.B skb->priority class encoding -only applies if the skb->priority holds a major:minor handle of an existing -class within this qdisc. -.TP -(ii) -tc filters attached to the class. -.TP -(iii) -The defmap of a class, as set with the -.B split & defmap -parameters. The defmap may contain instructions for each possible Linux packet -priority. - -.P -Each class also has a -.B level. -Leaf nodes, attached to the bottom of the class hierarchy, have a level of 0. -.SH CLASSIFICATION ALGORITHM - -Classification is a loop, which terminates when a leaf class is found. At any -point the loop may jump to the fallback algorithm. - -The loop consists of the following steps: -.TP -(i) -If the packet is generated locally and has a valid classid encoded within its -.B skb->priority, -choose it and terminate. - -.TP -(ii) -Consult the tc filters, if any, attached to this child. If these return -a class which is not a leaf class, restart loop from the class returned. -If it is a leaf, choose it and terminate. -.TP -(iii) -If the tc filters did not return a class, but did return a classid, -try to find a class with that id within this qdisc. -Check if the found class is of a lower -.B level -than the current class. If so, and the returned class is not a leaf node, -restart the loop at the found class. If it is a leaf node, terminate. -If we found an upward reference to a higher level, enter the fallback -algorithm. -.TP -(iv) -If the tc filters did not return a class, nor a valid reference to one, -consider the minor number of the reference to be the priority. Retrieve -a class from the defmap of this class for the priority. If this did not -contain a class, consult the defmap of this class for the -.B BEST_EFFORT -class. If this is an upward reference, or no -.B BEST_EFFORT -class was defined, -enter the fallback algorithm. If a valid class was found, and it is not a -leaf node, restart the loop at this class. If it is a leaf, choose it and -terminate. If -neither the priority distilled from the classid, nor the -.B BEST_EFFORT -priority yielded a class, enter the fallback algorithm. -.P -The fallback algorithm resides outside of the loop and is as follows. -.TP -(i) -Consult the defmap of the class at which the jump to fallback occured. If -the defmap contains a class for the -.B -priority -of the class (which is related to the TOS field), choose this class and -terminate. -.TP -(ii) -Consult the map for a class for the -.B BEST_EFFORT -priority. If found, choose it, and terminate. -.TP -(iii) -Choose the class at which break out to the fallback algorithm occured. Terminate. -.P -The packet is enqueued to the class which was chosen when either algorithm -terminated. It is therefore possible for a packet to be enqueued *not* at a -leaf node, but in the middle of the hierarchy. - -.SH LINK SHARING ALGORITHM -When dequeuing for sending to the network device, CBQ decides which of its -classes will be allowed to send. It does so with a Weighted Round Robin process -in which each class with packets gets a chance to send in turn. The WRR process -starts by asking the highest priority classes (lowest numerically - -highest semantically) for packets, and will continue to do so until they -have no more data to offer, in which case the process repeats for lower -priorities. - -.B CERTAINTY ENDS HERE, ANK PLEASE HELP - -Each class is not allowed to send at length though - they can only dequeue a -configurable amount of data during each round. - -If a class is about to go overlimit, and it is not -.B bounded -it will try to borrow avgidle from siblings that are not -.B isolated. -This process is repeated from the bottom upwards. If a class is unable -to borrow enough avgidle to send a packet, it is throttled and not asked -for a packet for enough time for the avgidle to increase above zero. - -.B I REALLY NEED HELP FIGURING THIS OUT. REST OF DOCUMENT IS PRETTY CERTAIN -.B AGAIN. - -.SH QDISC -The root qdisc of a CBQ class tree has the following parameters: - -.TP -parent major:minor | root -This mandatory parameter determines the place of the CBQ instance, either at the -.B root -of an interface or within an existing class. -.TP -handle major: -Like all other qdiscs, the CBQ can be assigned a handle. Should consist only -of a major number, followed by a colon. Optional. -.TP -avpkt bytes -For calculations, the average packet size must be known. It is silently capped -at a minimum of 2/3 of the interface MTU. Mandatory. -.TP -bandwidth rate -To determine the idle time, CBQ must know the bandwidth of your underlying -physical interface, or parent qdisc. This is a vital parameter, more about it -later. Mandatory. -.TP -cell -The cell size determines he granularity of packet transmission time calculations. Has a sensible default. -.TP -mpu -A zero sized packet may still take time to transmit. This value is the lower -cap for packet transmission time calculations - packets smaller than this value -are still deemed to have this size. Defaults to zero. -.TP -ewma log -When CBQ needs to measure the average idle time, it does so using an -Exponentially Weighted Moving Average which smoothes out measurements into -a moving average. The EWMA LOG determines how much smoothing occurs. Defaults -to 5. Lower values imply greater sensitivity. Must be between 0 and 31. -.P -A CBQ qdisc does not shape out of its own accord. It only needs to know certain -parameters about the underlying link. Actual shaping is done in classes. - -.SH CLASSES -Classes have a host of parameters to configure their operation. - -.TP -parent major:minor -Place of this class within the hierarchy. If attached directly to a qdisc -and not to another class, minor can be omitted. Mandatory. -.TP -classid major:minor -Like qdiscs, classes can be named. The major number must be equal to the -major number of the qdisc to which it belongs. Optional, but needed if this -class is going to have children. -.TP -weight weight -When dequeuing to the interface, classes are tried for traffic in a -round-robin fashion. Classes with a higher configured qdisc will generally -have more traffic to offer during each round, so it makes sense to allow -it to dequeue more traffic. All weights under a class are normalized, so -only the ratios matter. Defaults to the configured rate, unless the priority -of this class is maximal, in which case it is set to 1. -.TP -allot bytes -Allot specifies how many bytes a qdisc can dequeue -during each round of the process. This parameter is weighted using the -renormalized class weight described above. - -.TP -priority priority -In the round-robin process, classes with the lowest priority field are tried -for packets first. Mandatory. - -.TP -rate rate -Maximum rate this class and all its children combined can send at. Mandatory. - -.TP -bandwidth rate -This is different from the bandwidth specified when creating a CBQ disc. Only -used to determine maxidle and offtime, which are only calculated when -specifying maxburst or minburst. Mandatory if specifying maxburst or minburst. - -.TP -maxburst -This number of packets is used to calculate maxidle so that when -avgidle is at maxidle, this number of average packets can be burst -before avgidle drops to 0. Set it higher to be more tolerant of -bursts. You can't set maxidle directly, only via this parameter. - -.TP -minburst -As mentioned before, CBQ needs to throttle in case of -overlimit. The ideal solution is to do so for exactly the calculated -idle time, and pass 1 packet. However, Unix kernels generally have a -hard time scheduling events shorter than 10ms, so it is better to -throttle for a longer period, and then pass minburst packets in one -go, and then sleep minburst times longer. - -The time to wait is called the offtime. Higher values of minburst lead -to more accurate shaping in the long term, but to bigger bursts at -millisecond timescales. - -.TP -minidle -If avgidle is below 0, we are overlimits and need to wait until -avgidle will be big enough to send one packet. To prevent a sudden -burst from shutting down the link for a prolonged period of time, -avgidle is reset to minidle if it gets too low. - -Minidle is specified in negative microseconds, so 10 means that -avgidle is capped at -10us. - -.TP -bounded -Signifies that this class will not borrow bandwidth from its siblings. -.TP -isolated -Means that this class will not borrow bandwidth to its siblings - -.TP -split major:minor & defmap bitmap[/bitmap] -If consulting filters attached to a class did not give a verdict, -CBQ can also classify based on the packet's priority. There are 16 -priorities available, numbered from 0 to 15. - -The defmap specifies which priorities this class wants to receive, -specified as a bitmap. The Least Significant Bit corresponds to priority -zero. The -.B split -parameter tells CBQ at which class the decision must be made, which should -be a (grand)parent of the class you are adding. - -As an example, 'tc class add ... classid 10:1 cbq .. split 10:0 defmap c0' -configures class 10:0 to send packets with priorities 6 and 7 to 10:1. - -The complimentary configuration would then -be: 'tc class add ... classid 10:2 cbq ... split 10:0 defmap 3f' -Which would send all packets 0, 1, 2, 3, 4 and 5 to 10:1. -.TP -estimator interval timeconstant -CBQ can measure how much bandwidth each class is using, which tc filters -can use to classify packets with. In order to determine the bandwidth -it uses a very simple estimator that measures once every -.B interval -microseconds how much traffic has passed. This again is a EWMA, for which -the time constant can be specified, also in microseconds. The -.B time constant -corresponds to the sluggishness of the measurement or, conversely, to the -sensitivity of the average to short bursts. Higher values mean less -sensitivity. - - - -.SH SOURCES -.TP -o -Sally Floyd and Van Jacobson, "Link-sharing and Resource -Management Models for Packet Networks", -IEEE/ACM Transactions on Networking, Vol.3, No.4, 1995 - -.TP -o -Sally Floyd, "Notes on CBQ and Guarantee Service", 1995 - -.TP -o -Sally Floyd, "Notes on Class-Based Queueing: Setting -Parameters", 1996 - -.TP -o -Sally Floyd and Michael Speer, "Experimental Results -for Class-Based Queueing", 1998, not published. - - - -.SH SEE ALSO -.BR tc (8) - -.SH AUTHOR -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>. This manpage maintained by -bert hubert <ahu@ds9a.nl> - - diff --git a/tc-cbq.8 b/tc-cbq.8 deleted file mode 100644 index 79fb93b..0000000 --- a/tc-cbq.8 +++ /dev/null @@ -1,353 +0,0 @@ -.TH CBQ 8 "16 December 2001" "iproute2" "Linux" -.SH NAME -CBQ \- Class Based Queueing -.SH SYNOPSIS -.B tc qdisc ... dev -dev -.B ( parent -classid -.B | root) [ handle -major: -.B ] cbq [ allot -bytes -.B ] avpkt -bytes -.B bandwidth -rate -.B [ cell -bytes -.B ] [ ewma -log -.B ] [ mpu -bytes -.B ] - -.B tc class ... dev -dev -.B parent -major:[minor] -.B [ classid -major:minor -.B ] cbq allot -bytes -.B [ bandwidth -rate -.B ] [ rate -rate -.B ] prio -priority -.B [ weight -weight -.B ] [ minburst -packets -.B ] [ maxburst -packets -.B ] [ ewma -log -.B ] [ cell -bytes -.B ] avpkt -bytes -.B [ mpu -bytes -.B ] [ bounded isolated ] [ split -handle -.B & defmap -defmap -.B ] [ estimator -interval timeconstant -.B ] - -.SH DESCRIPTION -Class Based Queueing is a classful qdisc that implements a rich -linksharing hierarchy of classes. It contains shaping elements as -well as prioritizing capabilities. Shaping is performed using link -idle time calculations based on the timing of dequeue events and -underlying link bandwidth. - -.SH SHAPING ALGORITHM -When shaping a 10mbit/s connection to 1mbit/s, the link will -be idle 90% of the time. If it isn't, it needs to be throttled so that it -IS idle 90% of the time. - -During operations, the effective idletime is measured using an -exponential weighted moving average (EWMA), which considers recent -packets to be exponentially more important than past ones. The Unix -loadaverage is calculated in the same way. - -The calculated idle time is subtracted from the EWMA measured one, -the resulting number is called 'avgidle'. A perfectly loaded link has -an avgidle of zero: packets arrive exactly at the calculated -interval. - -An overloaded link has a negative avgidle and if it gets too negative, -CBQ throttles and is then 'overlimit'. - -Conversely, an idle link might amass a huge avgidle, which would then -allow infinite bandwidths after a few hours of silence. To prevent -this, avgidle is capped at -.B maxidle. - -If overlimit, in theory, the CBQ could throttle itself for exactly the -amount of time that was calculated to pass between packets, and then -pass one packet, and throttle again. Due to timer resolution constraints, -this may not be feasible, see the -.B minburst -parameter below. - -.SH CLASSIFICATION -Within the one CBQ instance many classes may exist. Each of these classes -contains another qdisc, by default -.BR tc-pfifo (8). - -When enqueueing a packet, CBQ starts at the root and uses various methods to -determine which class should receive the data. - -In the absence of uncommon configuration options, the process is rather easy. -At each node we look for an instruction, and then go to the class the -instruction refers us to. If the class found is a barren leaf-node (without -children), we enqueue the packet there. If it is not yet a leaf node, we do -the whole thing over again starting from that node. - -The following actions are performed, in order at each node we visit, until one -sends us to another node, or terminates the process. -.TP -(i) -Consult filters attached to the class. If sent to a leafnode, we are done. -Otherwise, restart. -.TP -(ii) -Consult the defmap for the priority assigned to this packet, which depends -on the TOS bits. Check if the referral is leafless, otherwise restart. -.TP -(iii) -Ask the defmap for instructions for the 'best effort' priority. Check the -answer for leafness, otherwise restart. -.TP -(iv) -If none of the above returned with an instruction, enqueue at this node. -.P -This algorithm makes sure that a packet always ends up somewhere, even while -you are busy building your configuration. - -For more details, see -.BR tc-cbq-details(8). - -.SH LINK SHARING ALGORITHM -When dequeuing for sending to the network device, CBQ decides which of its -classes will be allowed to send. It does so with a Weighted Round Robin process -in which each class with packets gets a chance to send in turn. The WRR process -starts by asking the highest priority classes (lowest numerically - -highest semantically) for packets, and will continue to do so until they -have no more data to offer, in which case the process repeats for lower -priorities. - -Classes by default borrow bandwidth from their siblings. A class can be -prevented from doing so by declaring it 'bounded'. A class can also indicate -its unwillingness to lend out bandwidth by being 'isolated'. - -.SH QDISC -The root of a CBQ qdisc class tree has the following parameters: - -.TP -parent major:minor | root -This mandatory parameter determines the place of the CBQ instance, either at the -.B root -of an interface or within an existing class. -.TP -handle major: -Like all other qdiscs, the CBQ can be assigned a handle. Should consist only -of a major number, followed by a colon. Optional, but very useful if classes -will be generated within this qdisc. -.TP -allot bytes -This allotment is the 'chunkiness' of link sharing and is used for determining packet -transmission time tables. The qdisc allot differs slightly from the class allot discussed -below. Optional. Defaults to a reasonable value, related to avpkt. -.TP -avpkt bytes -The average size of a packet is needed for calculating maxidle, and is also used -for making sure 'allot' has a safe value. Mandatory. -.TP -bandwidth rate -To determine the idle time, CBQ must know the bandwidth of your underlying -physical interface, or parent qdisc. This is a vital parameter, more about it -later. Mandatory. -.TP -cell -The cell size determines he granularity of packet transmission time calculations. Has a sensible default. -.TP -mpu -A zero sized packet may still take time to transmit. This value is the lower -cap for packet transmission time calculations - packets smaller than this value -are still deemed to have this size. Defaults to zero. -.TP -ewma log -When CBQ needs to measure the average idle time, it does so using an -Exponentially Weighted Moving Average which smoothes out measurements into -a moving average. The EWMA LOG determines how much smoothing occurs. Lower -values imply greater sensitivity. Must be between 0 and 31. Defaults -to 5. -.P -A CBQ qdisc does not shape out of its own accord. It only needs to know certain -parameters about the underlying link. Actual shaping is done in classes. - -.SH CLASSES -Classes have a host of parameters to configure their operation. - -.TP -parent major:minor -Place of this class within the hierarchy. If attached directly to a qdisc -and not to another class, minor can be omitted. Mandatory. -.TP -classid major:minor -Like qdiscs, classes can be named. The major number must be equal to the -major number of the qdisc to which it belongs. Optional, but needed if this -class is going to have children. -.TP -weight weight -When dequeuing to the interface, classes are tried for traffic in a -round-robin fashion. Classes with a higher configured qdisc will generally -have more traffic to offer during each round, so it makes sense to allow -it to dequeue more traffic. All weights under a class are normalized, so -only the ratios matter. Defaults to the configured rate, unless the priority -of this class is maximal, in which case it is set to 1. -.TP -allot bytes -Allot specifies how many bytes a qdisc can dequeue -during each round of the process. This parameter is weighted using the -renormalized class weight described above. Silently capped at a minimum of -3/2 avpkt. Mandatory. - -.TP -prio priority -In the round-robin process, classes with the lowest priority field are tried -for packets first. Mandatory. - -.TP -avpkt -See the QDISC section. - -.TP -rate rate -Maximum rate this class and all its children combined can send at. Mandatory. - -.TP -bandwidth rate -This is different from the bandwidth specified when creating a CBQ disc! Only -used to determine maxidle and offtime, which are only calculated when -specifying maxburst or minburst. Mandatory if specifying maxburst or minburst. - -.TP -maxburst -This number of packets is used to calculate maxidle so that when -avgidle is at maxidle, this number of average packets can be burst -before avgidle drops to 0. Set it higher to be more tolerant of -bursts. You can't set maxidle directly, only via this parameter. - -.TP -minburst -As mentioned before, CBQ needs to throttle in case of -overlimit. The ideal solution is to do so for exactly the calculated -idle time, and pass 1 packet. However, Unix kernels generally have a -hard time scheduling events shorter than 10ms, so it is better to -throttle for a longer period, and then pass minburst packets in one -go, and then sleep minburst times longer. - -The time to wait is called the offtime. Higher values of minburst lead -to more accurate shaping in the long term, but to bigger bursts at -millisecond timescales. Optional. - -.TP -minidle -If avgidle is below 0, we are overlimits and need to wait until -avgidle will be big enough to send one packet. To prevent a sudden -burst from shutting down the link for a prolonged period of time, -avgidle is reset to minidle if it gets too low. - -Minidle is specified in negative microseconds, so 10 means that -avgidle is capped at -10us. Optional. - -.TP -bounded -Signifies that this class will not borrow bandwidth from its siblings. -.TP -isolated -Means that this class will not borrow bandwidth to its siblings - -.TP -split major:minor & defmap bitmap[/bitmap] -If consulting filters attached to a class did not give a verdict, -CBQ can also classify based on the packet's priority. There are 16 -priorities available, numbered from 0 to 15. - -The defmap specifies which priorities this class wants to receive, -specified as a bitmap. The Least Significant Bit corresponds to priority -zero. The -.B split -parameter tells CBQ at which class the decision must be made, which should -be a (grand)parent of the class you are adding. - -As an example, 'tc class add ... classid 10:1 cbq .. split 10:0 defmap c0' -configures class 10:0 to send packets with priorities 6 and 7 to 10:1. - -The complimentary configuration would then -be: 'tc class add ... classid 10:2 cbq ... split 10:0 defmap 3f' -Which would send all packets 0, 1, 2, 3, 4 and 5 to 10:1. -.TP -estimator interval timeconstant -CBQ can measure how much bandwidth each class is using, which tc filters -can use to classify packets with. In order to determine the bandwidth -it uses a very simple estimator that measures once every -.B interval -microseconds how much traffic has passed. This again is a EWMA, for which -the time constant can be specified, also in microseconds. The -.B time constant -corresponds to the sluggishness of the measurement or, conversely, to the -sensitivity of the average to short bursts. Higher values mean less -sensitivity. - -.SH BUGS -The actual bandwidth of the underlying link may not be known, for example -in the case of PPoE or PPTP connections which in fact may send over a -pipe, instead of over a physical device. CBQ is quite resilient to major -errors in the configured bandwidth, probably a the cost of coarser shaping. - -Default kernels rely on coarse timing information for making decisions. These -may make shaping precise in the long term, but inaccurate on second long scales. - -See -.BR tc-cbq-details(8) -for hints on how to improve this. - -.SH SOURCES -.TP -o -Sally Floyd and Van Jacobson, "Link-sharing and Resource -Management Models for Packet Networks", -IEEE/ACM Transactions on Networking, Vol.3, No.4, 1995 - -.TP -o -Sally Floyd, "Notes on CBQ and Guaranteed Service", 1995 - -.TP -o -Sally Floyd, "Notes on Class-Based Queueing: Setting -Parameters", 1996 - -.TP -o -Sally Floyd and Michael Speer, "Experimental Results -for Class-Based Queueing", 1998, not published. - - - -.SH SEE ALSO -.BR tc (8) - -.SH AUTHOR -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>. This manpage maintained by -bert hubert <ahu@ds9a.nl> - - diff --git a/tc-htb.8 b/tc-htb.8 deleted file mode 100644 index f61b818..0000000 --- a/tc-htb.8 +++ /dev/null @@ -1,150 +0,0 @@ -.TH HTB 8 "10 January 2002" "iproute2" "Linux" -.SH NAME -HTB \- Hierarchy Token Bucket -.SH SYNOPSIS -.B tc qdisc ... dev -dev -.B ( parent -classid -.B | root) [ handle -major: -.B ] htb [ default -minor-id -.B ] - -.B tc class ... dev -dev -.B parent -major:[minor] -.B [ classid -major:minor -.B ] htb rate -rate -.B [ ceil -rate -.B ] burst -bytes -.B [ cburst -bytes -.B ] [ prio -priority -.B ] - -.SH DESCRIPTION -HTB is meant as a more understandable and intuitive replacement for -the CBQ qdisc in Linux. Both CBQ and HTB help you to control the use -of the outbound bandwidth on a given link. Both allow you to use one -physical link to simulate several slower links and to send different -kinds of traffic on different simulated links. In both cases, you have -to specify how to divide the physical link into simulated links and -how to decide which simulated link to use for a given packet to be sent. - -Unlike CBQ, HTB shapes traffic based on the Token Bucket Filter algorithm -which does not depend on interface characteristics and so does not need to -know the underlying bandwidth of the outgoing interface. - -.SH SHAPING ALGORITHM -Shaping works as documented in -.B tc-tbf (8). - -.SH CLASSIFICATION -Within the one HRB instance many classes may exist. Each of these classes -contains another qdisc, by default -.BR tc-pfifo (8). - -When enqueueing a packet, HTB starts at the root and uses various methods to -determine which class should receive the data. - -In the absence of uncommon configuration options, the process is rather easy. -At each node we look for an instruction, and then go to the class the -instruction refers us to. If the class found is a barren leaf-node (without -children), we enqueue the packet there. If it is not yet a leaf node, we do -the whole thing over again starting from that node. - -The following actions are performed, in order at each node we visit, until one -sends us to another node, or terminates the process. -.TP -(i) -Consult filters attached to the class. If sent to a leafnode, we are done. -Otherwise, restart. -.TP -(ii) -If none of the above returned with an instruction, enqueue at this node. -.P -This algorithm makes sure that a packet always ends up somewhere, even while -you are busy building your configuration. - -.SH LINK SHARING ALGORITHM -FIXME - -.SH QDISC -The root of a HTB qdisc class tree has the following parameters: - -.TP -parent major:minor | root -This mandatory parameter determines the place of the HTB instance, either at the -.B root -of an interface or within an existing class. -.TP -handle major: -Like all other qdiscs, the HTB can be assigned a handle. Should consist only -of a major number, followed by a colon. Optional, but very useful if classes -will be generated within this qdisc. -.TP -default minor-id -Unclassified traffic gets sent to the class with this minor-id. - -.SH CLASSES -Classes have a host of parameters to configure their operation. - -.TP -parent major:minor -Place of this class within the hierarchy. If attached directly to a qdisc -and not to another class, minor can be omitted. Mandatory. -.TP -classid major:minor -Like qdiscs, classes can be named. The major number must be equal to the -major number of the qdisc to which it belongs. Optional, but needed if this -class is going to have children. -.TP -prio priority -In the round-robin process, classes with the lowest priority field are tried -for packets first. Mandatory. - -.TP -rate rate -Maximum rate this class and all its children are guaranteed. Mandatory. - -.TP -ceil rate -Maximum rate at which a class can send, if its parent has bandwidth to spare. -Defaults to the configured rate, which implies no borrowing - -.TP -burst bytes -Amount of bytes that can be burst at -.B ceil -speed, in excess of the configured -.B rate. -Should be at least as high as the highest burst of all children. - -.TP -cburst bytes -Amount of bytes that can be burst at 'infinite' speed, in other words, as fast -as the interface can transmit them. For perfect evening out, should be equal to at most one average -packet. Should be at least as high as the highest cburst of all children. - -.SH NOTES -Due to Unix timing constraints, the maximum ceil rate is not infinite and may in fact be quite low. On Intel, -there are 100 timer events per second, the maximum rate is that rate at which 'burst' bytes are sent each timer tick. -From this, the mininum burst size for a specified rate can be calculated. For i386, a 10mbit rate requires a 12 kilobyte -burst as 100*12kb*8 equals 10mbit. - -.SH SEE ALSO -.BR tc (8) -.P -HTB website: http://luxik.cdi.cz/~devik/qos/htb/ -.SH AUTHOR -Martin Devera <devik@cdi.cz>. This manpage maintained by bert hubert <ahu@ds9a.nl> - - diff --git a/tc-pbfifo.8 b/tc-pbfifo.8 deleted file mode 100644 index 8dda4bb..0000000 --- a/tc-pbfifo.8 +++ /dev/null @@ -1,72 +0,0 @@ -.TH PBFIFO 8 "10 January 2002" "iproute2" "Linux" -.SH NAME -pfifo \- Packet limited First In, First Out queue -.P -bfifo \- Byte limited First In, First Out queue - -.SH SYNOPSIS -.B tc qdisc ... add pfifo -.B [ limit -packets -.B ] -.P -.B tc qdisc ... add bfifo -.B [ limit -bytes -.B ] - -.SH DESCRIPTION -The pfifo and bfifo qdiscs are unadorned First In, First Out queues. They are the -simplest queues possible and therefore have no overhead. -.B pfifo -constrains the queue size as measured in packets. -.B bfifo -does so as measured in bytes. - -Like all non-default qdiscs, they maintain statistics. This might be a reason to prefer -pfifo or bfifo over the default. - -.SH ALGORITHM -A list of packets is maintained, when a packet is enqueued it gets inserted at the tail of -a list. When a packet needs to be sent out to the network, it is taken from the head of the list. - -If the list is too long, no further packets are allowed on. This is called 'tail drop'. - -.SH PARAMETERS -.TP -limit -Maximum queue size. Specified in bytes for bfifo, in packets for pfifo. For pfifo, defaults -to the interface txqueuelen, as specified with -.BR ifconfig (8) -or -.BR ip (8). - -For bfifo, it defaults to the txqueuelen multiplied by the interface MTU. - -.SH OUTPUT -The output of -.B tc -s qdisc ls -contains the limit, either in packets or in bytes, and the number of bytes -and packets actually sent. An unsent and dropped packet only appears between braces -and is not counted as 'Sent'. - -In this example, the queue length is 100 packets, 45894 bytes were sent over 681 packets. -No packets were dropped, and as the pfifo queue does not slow down packets, there were also no -overlimits: -.P -.nf -# tc -s qdisc ls dev eth0 -qdisc pfifo 8001: dev eth0 limit 100p - Sent 45894 bytes 681 pkts (dropped 0, overlimits 0) -.fi - -If a backlog occurs, this is displayed as well. -.SH SEE ALSO -.BR tc (8) - -.SH AUTHORS -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru> - -This manpage maintained by bert hubert <ahu@ds9a.nl> - - diff --git a/tc-pfifo_fast.8 b/tc-pfifo_fast.8 deleted file mode 100644 index 43ab166..0000000 --- a/tc-pfifo_fast.8 +++ /dev/null @@ -1,59 +0,0 @@ -.TH PFIFO_FAST 8 "10 January 2002" "iproute2" "Linux" -.SH NAME -pfifo_fast \- three-band first in, first out queue - -.SH DESCRIPTION -pfifo_fast is the default qdisc of each interface. - -Whenever an interface is created, the pfifo_fast qdisc is automatically used -as a queue. If another qdisc is attached, it preempts the default -pfifo_fast, which automatically returns to function when an existing qdisc -is detached. - -In this sense this qdisc is magic, and unlike other qdiscs. - -.SH ALGORITHM -The algorithm is very similar to that of the classful -.BR tc-prio (8) -qdisc. -.B pfifo_fast -is like three -.BR tc-pfifo (8) -queues side by side, where packets can be enqueued in any of the three bands -based on their Type of Service bits or assigned priority. - -Not all three bands are dequeued simultaneously - as long as lower bands -have traffic, higher bands are never dequeued. This can be used to -prioritize interactive traffic or penalize 'lowest cost' traffic. - -Each band can be txqueuelen packets long, as configured with -.BR ifconfig (8) -or -.BR ip (8). -Additional packets coming in are not enqueued but are instead dropped. - -See -.BR tc-prio (8) -for complete details on how TOS bits are translated into bands. -.SH PARAMETERS -.TP -txqueuelen -The length of the three bands depends on the interface txqueuelen, as -specified with -.BR ifconfig (8) -or -.BR ip (8). - -.SH BUGS -Does not maintain statistics and does not show up in tc qdisc ls. This is because -it is the automatic default in the absence of a configured qdisc. - -.SH SEE ALSO -.BR tc (8) - -.SH AUTHORS -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru> - -This manpage maintained by bert hubert <ahu@ds9a.nl> - - diff --git a/tc-prio.8 b/tc-prio.8 deleted file mode 100644 index e942e62..0000000 --- a/tc-prio.8 +++ /dev/null @@ -1,187 +0,0 @@ -.TH PRIO 8 "16 December 2001" "iproute2" "Linux" -.SH NAME -PRIO \- Priority qdisc -.SH SYNOPSIS -.B tc qdisc ... dev -dev -.B ( parent -classid -.B | root) [ handle -major: -.B ] prio [ bands -bands -.B ] [ priomap -band,band,band... -.B ] [ estimator -interval timeconstant -.B ] - -.SH DESCRIPTION -The PRIO qdisc is a simple classful queueing discipline that contains -an arbitrary number of classes of differing priority. The classes are -dequeued in numerical descending order of priority. PRIO is a scheduler -and never delays packets - it is a work-conserving qdisc, though the qdiscs -contained in the classes may not be. - -Very useful for lowering latency when there is no need for slowing down -traffic. - -.SH ALGORITHM -On creation with 'tc qdisc add', a fixed number of bands is created. Each -band is a class, although is not possible to add classes with 'tc qdisc -add', the number of bands to be created must instead be specified on the -commandline attaching PRIO to its root. - -When dequeueing, band 0 is tried first and only if it did not deliver a -packet does PRIO try band 1, and so onwards. Maximum reliability packets -should therefore go to band 0, minimum delay to band 1 and the rest to band -2. - -As the PRIO qdisc itself will have minor number 0, band 0 is actually -major:1, band 1 is major:2, etc. For major, substitute the major number -assigned to the qdisc on 'tc qdisc add' with the -.B handle -parameter. - -.SH CLASSIFICATION -Three methods are available to PRIO to determine in which band a packet will -be enqueued. -.TP -From userspace -A process with sufficient privileges can encode the destination class -directly with SO_PRIORITY, see -.BR tc(7). -.TP -with a tc filter -A tc filter attached to the root qdisc can point traffic directly to a class -.TP -with the priomap -Based on the packet priority, which in turn is derived from the Type of -Service assigned to the packet. -.P -Only the priomap is specific to this qdisc. -.SH QDISC PARAMETERS -.TP -bands -Number of bands. If changed from the default of 3, -.B priomap -must be updated as well. -.TP -priomap -The priomap maps the priority of -a packet to a class. The priority can either be set directly from userspace, -or be derived from the Type of Service of the packet. - -Determines how packet priorities, as assigned by the kernel, map to -bands. Mapping occurs based on the TOS octet of the packet, which looks like -this: - -.nf -0 1 2 3 4 5 6 7 -+---+---+---+---+---+---+---+---+ -| | | | -|PRECEDENCE | TOS |MBZ| -| | | | -+---+---+---+---+---+---+---+---+ -.fi - -The four TOS bits (the 'TOS field') are defined as: - -.nf -Binary Decimcal Meaning ------------------------------------------ -1000 8 Minimize delay (md) -0100 4 Maximize throughput (mt) -0010 2 Maximize reliability (mr) -0001 1 Minimize monetary cost (mmc) -0000 0 Normal Service -.fi - -As there is 1 bit to the right of these four bits, the actual value of the -TOS field is double the value of the TOS bits. Tcpdump -v -v shows you the -value of the entire TOS field, not just the four bits. It is the value you -see in the first column of this table: - -.nf -TOS Bits Means Linux Priority Band ------------------------------------------------------------- -0x0 0 Normal Service 0 Best Effort 1 -0x2 1 Minimize Monetary Cost 1 Filler 2 -0x4 2 Maximize Reliability 0 Best Effort 1 -0x6 3 mmc+mr 0 Best Effort 1 -0x8 4 Maximize Throughput 2 Bulk 2 -0xa 5 mmc+mt 2 Bulk 2 -0xc 6 mr+mt 2 Bulk 2 -0xe 7 mmc+mr+mt 2 Bulk 2 -0x10 8 Minimize Delay 6 Interactive 0 -0x12 9 mmc+md 6 Interactive 0 -0x14 10 mr+md 6 Interactive 0 -0x16 11 mmc+mr+md 6 Interactive 0 -0x18 12 mt+md 4 Int. Bulk 1 -0x1a 13 mmc+mt+md 4 Int. Bulk 1 -0x1c 14 mr+mt+md 4 Int. Bulk 1 -0x1e 15 mmc+mr+mt+md 4 Int. Bulk 1 -.fi - -The second column contains the value of the relevant -four TOS bits, followed by their translated meaning. For example, 15 stands -for a packet wanting Minimal Montetary Cost, Maximum Reliability, Maximum -Throughput AND Minimum Delay. - -The fourth column lists the way the Linux kernel interprets the TOS bits, by -showing to which Priority they are mapped. - -The last column shows the result of the default priomap. On the commandline, -the default priomap looks like this: - - 1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1 - -This means that priority 4, for example, gets mapped to band number 1. -The priomap also allows you to list higher priorities (> 7) which do not -correspond to TOS mappings, but which are set by other means. - -This table from RFC 1349 (read it for more details) explains how -applications might very well set their TOS bits: - -.nf -TELNET 1000 (minimize delay) -FTP - Control 1000 (minimize delay) - Data 0100 (maximize throughput) - -TFTP 1000 (minimize delay) - -SMTP - Command phase 1000 (minimize delay) - DATA phase 0100 (maximize throughput) - -Domain Name Service - UDP Query 1000 (minimize delay) - TCP Query 0000 - Zone Transfer 0100 (maximize throughput) - -NNTP 0001 (minimize monetary cost) - -ICMP - Errors 0000 - Requests 0000 (mostly) - Responses <same as request> (mostly) -.fi - - -.SH CLASSES -PRIO classes cannot be configured further - they are automatically created -when the PRIO qdisc is attached. Each class however can contain yet a -further qdisc. - -.SH BUGS -Large amounts of traffic in the lower bands can cause starvation of higher -bands. Can be prevented by attaching a shaper (for example, -.BR tc-tbf(8) -to these bands to make sure they cannot dominate the link. - -.SH AUTHORS -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>, J Hadi Salim -<hadi@cyberus.ca>. This manpage maintained by bert hubert <ahu@ds9a.nl> - - diff --git a/tc-red.8 b/tc-red.8 deleted file mode 100644 index d02b411..0000000 --- a/tc-red.8 +++ /dev/null @@ -1,131 +0,0 @@ -.TH RED 8 "13 December 2001" "iproute2" "Linux" -.SH NAME -red \- Random Early Detection -.SH SYNOPSIS -.B tc qdisc ... red -.B limit -bytes -.B min -bytes -.B max -bytes -.B avpkt -bytes -.B burst -packets -.B [ ecn ] [ bandwidth -rate -.B ] probability -chance - -.SH DESCRIPTION -Random Early Detection is a classless qdisc which manages its queue size -smartly. Regular queues simply drop packets from the tail when they are -full, which may not be the optimal behaviour. RED also performs tail drop, -but does so in a more gradual way. - -Once the queue hits a certain average length, packets enqueued have a -configurable chance of being marked (which may mean dropped). This chance -increases linearly up to a point called the -.B max -average queue length, although the queue might get bigger. - -This has a host of benefits over simple taildrop, while not being processor -intensive. It prevents synchronous retransmits after a burst in traffic, -which cause further retransmits, etc. - -The goal is the have a small queue size, which is good for interactivity -while not disturbing TCP/IP traffic with too many sudden drops after a burst -of traffic. - -Depending on if ECN is configured, marking either means dropping or -purely marking a packet as overlimit. -.SH ALGORITHM -The average queue size is used for determining the marking -probability. This is calculated using an Exponential Weighted Moving -Average, which can be more or less sensitive to bursts. - -When the average queue size is below -.B min -bytes, no packet will ever be marked. When it exceeds -.B min, -the probability of doing so climbs linearly up -to -.B probability, -until the average queue size hits -.B max -bytes. Because -.B probability -is normally not set to 100%, the queue size might -conceivably rise above -.B max -bytes, so the -.B limit -parameter is provided to set a hard maximum for the size of the queue. - -.SH PARAMETERS -.TP -min -Average queue size at which marking becomes a possibility. -.TP -max -At this average queue size, the marking probability is maximal. Should be at -least twice -.B min -to prevent synchronous retransmits, higher for low -.B min. -.TP -probability -Maximum probability for marking, specified as a floating point -number from 0.0 to 1.0. Suggested values are 0.01 or 0.02 (1 or 2%, -respectively). -.TP -limit -Hard limit on the real (not average) queue size in bytes. Further packets -are dropped. Should be set higher than max+burst. It is advised to set this -a few times higher than -.B max. -.TP -burst -Used for determining how fast the average queue size is influenced by the -real queue size. Larger values make the calculation more sluggish, allowing -longer bursts of traffic before marking starts. Real life experiments -support the following guideline: (min+min+max)/(3*avpkt). -.TP -avpkt -Specified in bytes. Used with burst to determine the time constant for -average queue size calculations. 1000 is a good value. -.TP -bandwidth -This rate is used for calculating the average queue size after some -idle time. Should be set to the bandwidth of your interface. Does not mean -that RED will shape for you! Optional. -.TP -ecn -As mentioned before, RED can either 'mark' or 'drop'. Explicit Congestion -Notification allows RED to notify remote hosts that their rate exceeds the -amount of bandwidth available. Non-ECN capable hosts can only be notified by -dropping a packet. If this parameter is specified, packets which indicate -that their hosts honor ECN will only be marked and not dropped, unless the -queue size hits -.B limit -bytes. Needs a tc binary with RED support compiled in. Recommended. - -.SH SEE ALSO -.BR tc (8) - -.SH SOURCES -.TP -o -Floyd, S., and Jacobson, V., Random Early Detection gateways for -Congestion Avoidance. http://www.aciri.org/floyd/papers/red/red.html -.TP -o -Some changes to the algorithm by Alexey N. Kuznetsov. - -.SH AUTHORS -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>, Alexey Makarenko -<makar@phoenix.kharkov.ua>, J Hadi Salim <hadi@nortelnetworks.com>. -This manpage maintained by bert hubert <ahu@ds9a.nl> - - diff --git a/tc-sfq.8 b/tc-sfq.8 deleted file mode 100644 index 337c795..0000000 --- a/tc-sfq.8 +++ /dev/null @@ -1,107 +0,0 @@ -.TH TC 8 "8 December 2001" "iproute2" "Linux" -.SH NAME -sfq \- Stochastic Fairness Queueing -.SH SYNOPSIS -.B tc qdisc ... perturb -seconds -.B quantum -bytes - -.SH DESCRIPTION - -Stochastic Fairness Queueing is a classless queueing discipline available for -traffic control with the -.BR tc (8) -command. - -SFQ does not shape traffic but only schedules the transmission of packets, based on 'flows'. -The goal is to ensure fairness so that each flow is able to send data in turn, thus preventing -any single flow from drowning out the rest. - -This may in fact have some effect in mitigating a Denial of Service attempt. - -SFQ is work-conserving and therefore always delivers a packet if it has one available. -.SH ALGORITHM -On enqueueing, each packet is assigned to a hash bucket, based on -.TP -(i) -Source address -.TP -(ii) -Destination address -.TP -(iii) -Source port -.P -If these are available. SFQ knows about ipv4 and ipv6 and also UDP, TCP and ESP. -Packets with other protocols are hashed based on the 32bits representation of their -destination and the socket they belong to. A flow corresponds mostly to a TCP/IP -connection. - -Each of these buckets should represent a unique flow. Because multiple flows may -get hashed to the same bucket, the hashing algorithm is perturbed at configurable -intervals so that the unfairness lasts only for a short while. Perturbation may -however cause some inadvertent packet reordering to occur. - -When dequeuing, each hashbucket with data is queried in a round robin fashion. - -The compile time maximum length of the SFQ is 128 packets, which can be spread over -at most 128 buckets of 1024 available. In case of overflow, tail-drop is performed -on the fullest bucket, thus maintaining fairness. - -.SH PARAMETERS -.TP -perturb -Interval in seconds for queue algorithm perturbation. Defaults to 0, which means that -no perturbation occurs. Do not set too low for each perturbation may cause some packet -reordering. Advised value: 10 -.TP -quantum -Amount of bytes a flow is allowed to dequeue during a round of the round robin process. -Defaults to the MTU of the interface which is also the advised value and the minimum value. - -.SH EXAMPLE & USAGE - -To attach to device ppp0: -.P -# tc qdisc add dev ppp0 root sfq perturb 10 -.P -Please note that SFQ, like all non-shaping (work-conserving) qdiscs, is only useful -if it owns the queue. -This is the case when the link speed equals the actually available bandwidth. This holds -for regular phone modems, ISDN connections and direct non-switched ethernet links. -.P -Most often, cable modems and DSL devices do not fall into this category. The same holds -for when connected to a switch and trying to send data to a congested segment also -connected to the switch. -.P -In this case, the effective queue does not reside within Linux and is therefore not -available for scheduling. -.P -Embed SFQ in a classful qdisc to make sure it owns the queue. - -.SH SOURCE -.TP -o -Paul E. McKenney "Stochastic Fairness Queuing", -IEEE INFOCOMM'90 Proceedings, San Francisco, 1990. - -.TP -o -Paul E. McKenney "Stochastic Fairness Queuing", -"Interworking: Research and Experience", v.2, 1991, p.113-131. - -.TP -o -See also: -M. Shreedhar and George Varghese "Efficient Fair -Queuing using Deficit Round Robin", Proc. SIGCOMM 95. - -.SH SEE ALSO -.BR tc (8) - -.SH AUTHOR -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>. This manpage maintained by -bert hubert <ahu@ds9a.nl> - - diff --git a/tc-tbf.8 b/tc-tbf.8 deleted file mode 100644 index 3abb238..0000000 --- a/tc-tbf.8 +++ /dev/null @@ -1,138 +0,0 @@ -.TH TC 8 "13 December 2001" "iproute2" "Linux" -.SH NAME -tbf \- Token Bucket Filter -.SH SYNOPSIS -.B tc qdisc ... tbf rate -rate -.B burst -bytes/cell -.B ( latency -ms -.B | limit -bytes -.B ) [ mpu -bytes -.B [ peakrate -rate -.B mtu -bytes/cell -.B ] ] -.P -burst is also known as buffer and maxburst. mtu is also known as minburst. -.SH DESCRIPTION - -The Token Bucket Filter is a classless queueing discipline available for -traffic control with the -.BR tc (8) -command. - -TBF is a pure shaper and never schedules traffic. It is non-work-conserving and may throttle -itself, although packets are available, to ensure that the configured rate is not exceeded. -On all platforms except for Alpha, -it is able to shape up to 1mbit/s of normal traffic with ideal minimal burstiness, -sending out data exactly at the configured rates. - -Much higher rates are possible but at the cost of losing the minimal burstiness. In that -case, data is on average dequeued at the configured rate but may be sent much faster at millisecond -timescales. Because of further queues living in network adaptors, this is often not a problem. - -Kernels with a higher 'HZ' can achieve higher rates with perfect burstiness. On Alpha, HZ is ten -times higher, leading to a 10mbit/s limit to perfection. These calculations hold for packets of on -average 1000 bytes. - -.SH ALGORITHM -As the name implies, traffic is filtered based on the expenditure of -.B tokens. -Tokens roughly correspond to bytes, with the additional constraint that each packet consumes -some tokens, no matter how small it is. This reflects the fact that even a zero-sized packet occupies -the link for some time. - -On creation, the TBF is stocked with tokens which correspond to the amount of traffic that can be burst -in one go. Tokens arrive at a steady rate, until the bucket is full. - -If no tokens are available, packets are queued, up to a configured limit. The TBF now -calculates the token deficit, and throttles until the first packet in the queue can be sent. - -If it is not acceptable to burst out packets at maximum speed, a peakrate can be configured -to limit the speed at which the bucket empties. This peakrate is implemented as a second TBF -with a very small bucket, so that it doesn't burst. - -To achieve perfection, the second bucket may contain only a single packet, which leads to -the earlier mentioned 1mbit/s limit. - -This limit is caused by the fact that the kernel can only throttle for at minimum 1 'jiffy', which depends -on HZ as 1/HZ. For perfect shaping, only a single packet can get sent per jiffy - for HZ=100, this means 100 -packets of on average 1000 bytes each, which roughly corresponds to 1mbit/s. - -.SH PARAMETERS -See -.BR tc (8) -for how to specify the units of these values. -.TP -limit or latency -Limit is the number of bytes that can be queued waiting for tokens to become -available. You can also specify this the other way around by setting the -latency parameter, which specifies the maximum amount of time a packet can -sit in the TBF. The latter calculation takes into account the size of the -bucket, the rate and possibly the peakrate (if set). These two parameters -are mutually exclusive. -.TP -burst -Also known as buffer or maxburst. -Size of the bucket, in bytes. This is the maximum amount of bytes that tokens can be available for instantaneously. -In general, larger shaping rates require a larger buffer. For 10mbit/s on Intel, you need at least 10kbyte buffer -if you want to reach your configured rate! - -If your buffer is too small, packets may be dropped because more tokens arrive per timer tick than fit in your bucket. -The minimum buffer size can be calculated by dividing the rate by HZ. - -Token usage calculations are performed using a table which by default has a resolution of 8 packets. -This resolution can be changed by specifying the -.B cell -size with the burst. For example, to specify a 6000 byte buffer with a 16 -byte cell size, set a burst of 6000/16. You will probably never have to set -this. Must be an integral power of 2. -.TP -mpu -A zero-sized packet does not use zero bandwidth. For ethernet, no packet uses less than 64 bytes. The Minimum Packet Unit -determines the minimal token usage (specified in bytes) for a packet. Defaults to zero. -.TP -rate -The speed knob. See remarks above about limits! See -.BR tc (8) -for units. -.PP -Furthermore, if a peakrate is desired, the following parameters are available: - -.TP -peakrate -Maximum depletion rate of the bucket. Limited to 1mbit/s on Intel, 10mbit/s on Alpha. The peakrate does -not need to be set, it is only necessary if perfect millisecond timescale shaping is required. - -.TP -mtu/minburst -Specifies the size of the peakrate bucket. For perfect accuracy, should be set to the MTU of the interface. -If a peakrate is needed, but some burstiness is acceptable, this size can be raised. A 3000 byte minburst -allows around 3mbit/s of peakrate, given 1000 byte packets. - -Like the regular burstsize you can also specify a -.B cell -size. -.SH EXAMPLE & USAGE - -To attach a TBF with a sustained maximum rate of 0.5mbit/s, a peakrate of 1.0mbit/s, -a 5kilobyte buffer, with a pre-bucket queue size limit calculated so the TBF causes -at most 70ms of latency, with perfect peakrate behaviour, issue: -.P -# tc qdisc add dev eth0 root tbf rate 0.5mbit \\ - burst 5kb latency 70ms peakrate 1mbit \\ - minburst 1540 - -.SH SEE ALSO -.BR tc (8) - -.SH AUTHOR -Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>. This manpage maintained by -bert hubert <ahu@ds9a.nl> - - diff --git a/tc.8 b/tc.8 deleted file mode 100644 index b9b8039..0000000 --- a/tc.8 +++ /dev/null @@ -1,348 +0,0 @@ -.TH TC 8 "16 December 2001" "iproute2" "Linux" -.SH NAME -tc \- show / manipulate traffic control settings -.SH SYNOPSIS -.B tc qdisc [ add | change | replace | link ] dev -DEV -.B -[ parent -qdisc-id -.B | root ] -.B [ handle -qdisc-id ] qdisc -[ qdisc specific parameters ] -.P - -.B tc class [ add | change | replace ] dev -DEV -.B parent -qdisc-id -.B [ classid -class-id ] qdisc -[ qdisc specific parameters ] -.P - -.B tc filter [ add | change | replace ] dev -DEV -.B [ parent -qdisc-id -.B | root ] protocol -protocol -.B prio -priority filtertype -[ filtertype specific parameters ] -.B flowid -flow-id - -.B tc [-s | -d ] qdisc show [ dev -DEV -.B ] -.P -.B tc [-s | -d ] class show dev -DEV -.P -.B tc filter show dev -DEV - -.SH DESCRIPTION -.B Tc -is used to configure Traffic Control in the Linux kernel. Traffic Control consists -of the following: - -.TP -SHAPING -When traffic is shaped, its rate of transmission is under control. Shaping may -be more than lowering the available bandwidth - it is also used to smooth out -bursts in traffic for better network behaviour. Shaping occurs on egress. - -.TP -SCHEDULING -By scheduling the transmission of packets it is possible to improve interactivity -for traffic that needs it while still guaranteeing bandwidth to bulk transfers. Reordering -is also called prioritizing, and happens only on egress. - -.TP -POLICING -Where shaping deals with transmission of traffic, policing pertains to traffic -arriving. Policing thus occurs on ingress. - -.TP -DROPPING -Traffic exceeding a set bandwidth may also be dropped forthwith, both on -ingress and on egress. - -.P -Processing of traffic is controlled by three kinds of objects: qdiscs, -classes and filters. - -.SH QDISCS -.B qdisc -is short for 'queueing discipline' and it is elementary to -understanding traffic control. Whenever the kernel needs to send a -packet to an interface, it is -.B enqueued -to the qdisc configured for that interface. Immediately afterwards, the kernel -tries to get as many packets as possible from the qdisc, for giving them -to the network adaptor driver. - -A simple QDISC is the 'pfifo' one, which does no processing at all and is a pure -First In, First Out queue. It does however store traffic when the network interface -can't handle it momentarily. - -.SH CLASSES -Some qdiscs can contain classes, which contain further qdiscs - traffic may -then be enqueued in any of the inner qdiscs, which are within the -.B classes. -When the kernel tries to dequeue a packet from such a -.B classful qdisc -it can come from any of the classes. A qdisc may for example prioritize -certain kinds of traffic by trying to dequeue from certain classes -before others. - -.SH FILTERS -A -.B filter -is used by a classful qdisc to determine in which class a packet will -be enqueued. Whenever traffic arrives at a class with subclasses, it needs -to be classified. Various methods may be employed to do so, one of these -are the filters. All filters attached to the class are called, until one of -them returns with a verdict. If no verdict was made, other criteria may be -available. This differs per qdisc. - -It is important to notice that filters reside -.B within -qdiscs - they are not masters of what happens. - -.SH CLASSLESS QDISCS -The classless qdiscs are: -.TP -[p|b]fifo -Simplest usable qdisc, pure First In, First Out behaviour. Limited in -packets or in bytes. -.TP -pfifo_fast -Standard qdisc for 'Advanced Router' enabled kernels. Consists of a three-band -queue which honors Type of Service flags, as well as the priority that may be -assigned to a packet. -.TP -red -Random Early Detection simulates physical congestion by randomly dropping -packets when nearing configured bandwidth allocation. Well suited to very -large bandwidth applications. -.TP -sfq -Stochastic Fairness Queueing reorders queued traffic so each 'session' -gets to send a packet in turn. -.TP -tbf -The Token Bucket Filter is suited for slowing traffic down to a precisely -configured rate. Scales well to large bandwidths. -.SH CONFIGURING CLASSLESS QDISCS -In the absence of classful qdiscs, classless qdiscs can only be attached at -the root of a device. Full syntax: -.P -.B tc qdisc add dev -DEV -.B root -QDISC QDISC-PARAMETERS - -To remove, issue -.P -.B tc qdisc del dev -DEV -.B root - -The -.B pfifo_fast -qdisc is the automatic default in the absence of a configured qdisc. - -.SH CLASSFUL QDISCS -The classful qdiscs are: -.TP -CBQ -Class Based Queueing implements a rich linksharing hierarchy of classes. -It contains shaping elements as well as prioritizing capabilities. Shaping is -performed using link idle time calculations based on average packet size and -underlying link bandwidth. The latter may be ill-defined for some interfaces. -.TP -HTB -The Hierarchy Token Bucket implements a rich linksharing hierarchy of -classes with an emphasis on conforming to existing practices. HTB facilitates -guaranteeing bandwidth to classes, while also allowing specification of upper -limits to inter-class sharing. It contains shaping elements, based on TBF and -can prioritize classes. -.TP -PRIO -The PRIO qdisc is a non-shaping container for a configurable number of -classes which are dequeued in order. This allows for easy prioritization -of traffic, where lower classes are only able to send if higher ones have -no packets available. To facilitate configuration, Type Of Service bits are -honored by default. -.SH THEORY OF OPERATION -Classes form a tree, where each class has a single parent. -A class may have multiple children. Some qdiscs allow for runtime addition -of classes (CBQ, HTB) while others (PRIO) are created with a static number of -children. - -Qdiscs which allow dynamic addition of classes can have zero or more -subclasses to which traffic may be enqueued. - -Furthermore, each class contains a -.B leaf qdisc -which by default has -.B pfifo -behaviour though another qdisc can be attached in place. This qdisc may again -contain classes, but each class can have only one leaf qdisc. - -When a packet enters a classful qdisc it can be -.B classified -to one of the classes within. Three criteria are available, although not all -qdiscs will use all three: -.TP -tc filters -If tc filters are attached to a class, they are consulted first -for relevant instructions. Filters can match on all fields of a packet header, -as well as on the firewall mark applied by ipchains or iptables. See -.BR tc-filters (8). -.TP -Type of Service -Some qdiscs have built in rules for classifying packets based on the TOS field. -.TP -skb->priority -Userspace programs can encode a class-id in the 'skb->priority' field using -the SO_PRIORITY option. -.P -Each node within the tree can have its own filters but higher level filters -may also point directly to lower classes. - -If classification did not succeed, packets are enqueued to the leaf qdisc -attached to that class. Check qdisc specific manpages for details, however. - -.SH NAMING -All qdiscs, classes and filters have IDs, which can either be specified -or be automatically assigned. - -IDs consist of a major number and a minor number, separated by a colon. - -.TP -QDISCS -A qdisc, which potentially can have children, -gets assigned a major number, called a 'handle', leaving the minor -number namespace available for classes. The handle is expressed as '10:'. -It is customary to explicitly assign a handle to qdiscs expected to have -children. - -.TP -CLASSES -Classes residing under a qdisc share their qdisc major number, but each have -a separate minor number called a 'classid' that has no relation to their -parent classes, only to their parent qdisc. The same naming custom as for -qdiscs applies. - -.TP -FILTERS -Filters have a three part ID, which is only needed when using a hashed -filter hierarchy, for which see -.BR tc-filters (8). -.SH UNITS -All parameters accept a floating point number, possibly followed by a unit. -.P -Bandwidths or rates can be specified in: -.TP -kbps -Kilobytes per second -.TP -mbps -Megabytes per second -.TP -kbit -Kilobits per second -.TP -mbit -Megabits per second -.TP -bps or a bare number -Bytes per second -.P -Amounts of data can be specified in: -.TP -kb or k -Kilobytes -.TP -mb or m -Megabytes -.TP -mbit -Megabits -.TP -kbit -Kilobits -.TP -b or a bare number -Bytes. -.P -Lengths of time can be specified in: -.TP -s, sec or secs -Whole seconds -.TP -ms, msec or msecs -Milliseconds -.TP -us, usec, usecs or a bare number -Microseconds. - -.SH TC COMMANDS -The following commands are available for qdiscs, classes and filter: -.TP -add -Add a qdisc, class or filter to a node. For all entities, a -.B parent -must be passed, either by passing its ID or by attaching directly to the root of a device. -When creating a qdisc or a filter, it can be named with the -.B handle -parameter. A class is named with the -.B classid -parameter. - -.TP -remove -A qdisc can be removed by specifying its handle, which may also be 'root'. All subclasses and their leaf qdiscs -are automatically deleted, as well as any filters attached to them. - -.TP -change -Some entities can be modified 'in place'. Shares the syntax of 'add', with the exception -that the handle cannot be changed and neither can the parent. In other words, -.B -change -cannot move a node. - -.TP -replace -Performs a nearly atomic remove/add on an existing node id. If the node does not exist yet -it is created. - -.TP -link -Only available for qdiscs and performs a replace where the node -must exist already. - - -.SH HISTORY -.B tc -was written by Alexey N. Kuznetsov and added in Linux 2.2. -.SH SEE ALSO -.BR tc-cbq (8), -.BR tc-htb (8), -.BR tc-sfq (8), -.BR tc-red (8), -.BR tc-tbf (8), -.BR tc-pfifo (8), -.BR tc-bfifo (8), -.BR tc-pfifo_fast (8), -.BR tc-filters (8) - -.SH AUTHOR -Manpage maintained by bert hubert (ahu@ds9a.nl) - diff --git a/tc/Makefile b/tc/Makefile deleted file mode 100644 index 9d618ff..0000000 --- a/tc/Makefile +++ /dev/null @@ -1,89 +0,0 @@ -TCOBJ= tc.o tc_qdisc.o tc_class.o tc_filter.o tc_util.o \ - m_police.o m_estimator.o m_action.o m_ematch.o \ - emp_ematch.yacc.o emp_ematch.lex.o - -include ../Config - -TCMODULES := -TCMODULES += q_fifo.o -TCMODULES += q_sfq.o -TCMODULES += q_red.o -TCMODULES += q_prio.o -TCMODULES += q_tbf.o -TCMODULES += q_cbq.o -TCMODULES += f_rsvp.o -TCMODULES += f_u32.o -TCMODULES += f_route.o -TCMODULES += f_fw.o -TCMODULES += f_basic.o -TCMODULES += q_dsmark.o -TCMODULES += q_gred.o -TCMODULES += f_tcindex.o -TCMODULES += q_ingress.o -TCMODULES += q_hfsc.o -TCMODULES += q_htb.o -TCMODULES += m_gact.o -TCMODULES += m_mirred.o -TCMODULES += m_ipt.o -TCMODULES += m_pedit.o -TCMODULES += p_ip.o -TCMODULES += p_icmp.o -TCMODULES += p_tcp.o -TCMODULES += p_udp.o -TCMODULES += em_nbyte.o -TCMODULES += em_cmp.o -TCMODULES += em_u32.o -TCMODULES += em_meta.o - -TCOBJ += $(TCMODULES) - -TCLIB := tc_core.o -TCLIB += tc_red.o -TCLIB += tc_cbq.o -TCLIB += tc_estimator.o - -CFLAGS += -DCONFIG_GACT -DCONFIG_GACT_PROB - -TCSO := -TCSO += q_netem.so -ifeq ($(TC_CONFIG_ATM),y) - TCSO += q_atm.so -endif - -LDLIBS += -L. -ltc -lm -ldl - -LDFLAGS += -Wl,-export-dynamic - -YACC := bison -LEX := flex - -%.so: %.c - $(CC) $(CFLAGS) -shared -fpic $< -o $@ - - -all: libtc.a tc $(TCSO) - -tc: $(TCOBJ) $(LIBNETLINK) $(LIBUTIL) $(TCLIB) - -libtc.a: $(TCLIB) - $(AR) rcs $@ $(TCLIB) - -install: all - mkdir -p $(DESTDIR)/usr/lib/tc - install -m 0755 -s tc $(DESTDIR)$(SBINDIR) - for i in $(TCSO); \ - do install -m 755 -s $$i $(DESTDIR)/usr/lib/tc; \ - done - -clean: - rm -f $(TCOBJ) $(TCLIB) libtc.a tc *.so emp_ematch.yacc.h; \ - rm -f emp_ematch.yacc.output - -q_atm.so: q_atm.c - $(CC) $(CFLAGS) -shared -fpic -o q_atm.so q_atm.c -latm - -%.yacc.c: %.y - $(YACC) $(YACCFLAGS) -o $@ $< - -%.lex.c: %.l - $(LEX) $(LEXFLAGS) -o$@ $< diff --git a/tc/README.last b/tc/README.last deleted file mode 100644 index 9400438..0000000 --- a/tc/README.last +++ /dev/null @@ -1,47 +0,0 @@ -Kernel code and interface. --------------------------- - -* Compile time switches - -There is only one, but very important, compile time switch. -It is not settable by "make config", but should be selected -manually and after a bit of thinking in <include/net/pkt_sched.h> - -PSCHED_CLOCK_SOURCE can take three values: - - PSCHED_GETTIMEOFDAY - PSCHED_JIFFIES - PSCHED_CPU - - - PSCHED_GETTIMEOFDAY - -Default setting is the most conservative PSCHED_GETTIMEOFDAY. -It is very slow both because of weird slowness of do_gettimeofday() -and because it forces code to use unnatural "timeval" format, -where microseconds and seconds fields are separate. -Besides that, it will misbehave, when delays exceed 2 seconds -(f.e. very slow links or classes bounded to small slice of bandwidth) -To resume: as only you will get it working, select correct clock -source and forget about PSCHED_GETTIMEOFDAY forever. - - - PSCHED_JIFFIES - -Clock is derived from jiffies. On architectures with HZ=100 -granularity of this clock is not enough to make reasonable -bindings to real time. However, taking into account Linux -architecture problems, which force us to use artificial -integrated clock in any case, this switch is not so bad -for schduling even on high speed networks, though policing -is not reliable. - - - PSCHED_CPU - -It is available only for alpha and pentiums with correct -CPU timestamp. It is the fastest way, use it when it is available, -but remember: not all pentiums have this facility, and -a lot of them have clock, broken by APM etc. etc. - - diff --git a/tc/em_cmp.c b/tc/em_cmp.c deleted file mode 100644 index c636c53..0000000 --- a/tc/em_cmp.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * em_cmp.c Simle coparison Ematch - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Thomas Graf <tgraf@suug.ch> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <dlfcn.h> -#include <errno.h> - -#include "m_ematch.h" -#include <linux/tc_ematch/tc_em_cmp.h> - -extern struct ematch_util cmp_ematch_util; - -static void cmp_print_usage(FILE *fd) -{ - fprintf(fd, - "Usage: cmp(ALIGN at OFFSET [ ATTRS ] { eq | lt | gt } VALUE)\n" \ - "where: ALIGN := { u8 | u16 | u32 }\n" \ - " ATTRS := [ layer LAYER ] [ mask MASK ] [ trans ]\n" \ - " LAYER := { link | header | next-header | 0..%d }\n" \ - "\n" \ - "Example: cmp(u16 at 3 layer 2 mask 0xff00 gt 20)\n", - TCF_LAYER_MAX); -} - -static int cmp_parse_eopt(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr, - struct bstr *args) -{ - struct bstr *a; - int align, opnd = 0; - unsigned long offset = 0, layer = TCF_LAYER_NETWORK, mask = 0, value = 0; - int offset_present = 0, value_present = 0; - struct tcf_em_cmp cmp; - - memset(&cmp, 0, sizeof(cmp)); - -#define PARSE_ERR(CARG, FMT, ARGS...) \ - em_parse_error(EINVAL, args, CARG, &cmp_ematch_util, FMT ,##ARGS) - - if (args == NULL) - return PARSE_ERR(args, "cmp: missing arguments"); - - if (!bstrcmp(args, "u8")) - align = TCF_EM_ALIGN_U8; - else if (!bstrcmp(args, "u16")) - align = TCF_EM_ALIGN_U16; - else if (!bstrcmp(args, "u32")) - align = TCF_EM_ALIGN_U32; - else - return PARSE_ERR(args, "cmp: invalid alignment"); - - for (a = bstr_next(args); a; a = bstr_next(a)) { - if (!bstrcmp(a, "at")) { - if (a->next == NULL) - return PARSE_ERR(a, "cmp: missing argument"); - a = bstr_next(a); - - offset = bstrtoul(a); - if (offset == ULONG_MAX) - return PARSE_ERR(a, "cmp: invalid offset, " \ - "must be numeric"); - - offset_present = 1; - } else if (!bstrcmp(a, "layer")) { - if (a->next == NULL) - return PARSE_ERR(a, "cmp: missing argument"); - a = bstr_next(a); - - layer = parse_layer(a); - if (layer == INT_MAX) { - layer = bstrtoul(a); - if (layer == ULONG_MAX) - return PARSE_ERR(a, "cmp: invalid " \ - "layer"); - } - - if (layer > TCF_LAYER_MAX) - return PARSE_ERR(a, "cmp: illegal layer, " \ - "must be in 0..%d", TCF_LAYER_MAX); - } else if (!bstrcmp(a, "mask")) { - if (a->next == NULL) - return PARSE_ERR(a, "cmp: missing argument"); - a = bstr_next(a); - - mask = bstrtoul(a); - if (mask == ULONG_MAX) - return PARSE_ERR(a, "cmp: invalid mask"); - } else if (!bstrcmp(a, "trans")) { - cmp.flags |= TCF_EM_CMP_TRANS; - } else if (!bstrcmp(a, "eq") || !bstrcmp(a, "gt") || - !bstrcmp(a, "lt")) { - - if (!bstrcmp(a, "eq")) - opnd = TCF_EM_OPND_EQ; - else if (!bstrcmp(a, "gt")) - opnd = TCF_EM_OPND_GT; - else if (!bstrcmp(a, "lt")) - opnd = TCF_EM_OPND_LT; - - if (a->next == NULL) - return PARSE_ERR(a, "cmp: missing argument"); - a = bstr_next(a); - - value = bstrtoul(a); - if (value == ULONG_MAX) - return PARSE_ERR(a, "cmp: invalid value"); - - value_present = 1; - } else - return PARSE_ERR(a, "nbyte: unknown parameter"); - } - - if (offset_present == 0 || value_present == 0) - return PARSE_ERR(a, "cmp: offset and value required"); - - cmp.val = (__u32) value; - cmp.mask = (__u32) mask; - cmp.off = (__u16) offset; - cmp.align = (__u8) align; - cmp.layer = (__u8) layer; - cmp.opnd = (__u8) opnd; - - addraw_l(n, MAX_MSG, hdr, sizeof(*hdr)); - addraw_l(n, MAX_MSG, &cmp, sizeof(cmp)); - -#undef PARSE_ERR - return 0; -} - -static int cmp_print_eopt(FILE *fd, struct tcf_ematch_hdr *hdr, void *data, - int data_len) -{ - struct tcf_em_cmp *cmp = data; - - if (data_len < sizeof(*cmp)) { - fprintf(stderr, "CMP header size mismatch\n"); - return -1; - } - - if (cmp->align == TCF_EM_ALIGN_U8) - fprintf(fd, "u8 "); - else if (cmp->align == TCF_EM_ALIGN_U16) - fprintf(fd, "u16 "); - else if (cmp->align == TCF_EM_ALIGN_U16) - fprintf(fd, "u32 "); - - fprintf(fd, "at %d layer %d ", cmp->off, cmp->layer); - - if (cmp->mask) - fprintf(fd, "mask 0x%x ", cmp->mask); - - if (cmp->flags & TCF_EM_CMP_TRANS) - fprintf(fd, "trans "); - - if (cmp->opnd == TCF_EM_OPND_EQ) - fprintf(fd, "eq "); - else if (cmp->opnd == TCF_EM_OPND_LT) - fprintf(fd, "lt "); - else if (cmp->opnd == TCF_EM_OPND_GT) - fprintf(fd, "gt "); - - fprintf(fd, "%d", cmp->val); - - return 0; -} - -struct ematch_util cmp_ematch_util = { - .kind = "cmp", - .kind_num = TCF_EM_CMP, - .parse_eopt = cmp_parse_eopt, - .print_eopt = cmp_print_eopt, - .print_usage = cmp_print_usage -}; diff --git a/tc/em_meta.c b/tc/em_meta.c deleted file mode 100644 index bd1e151..0000000 --- a/tc/em_meta.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - * em_meta.c Metadata Ematch - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Thomas Graf <tgraf@suug.ch> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <dlfcn.h> -#include <errno.h> - -#include "m_ematch.h" -#include <linux/tc_ematch/tc_em_meta.h> - -extern struct ematch_util meta_ematch_util; - -static void meta_print_usage(FILE *fd) -{ - fprintf(fd, - "Usage: meta(OBJECT { eq | lt | gt } OBJECT)\n" \ - "where: OBJECT := { META_ID | VALUE }\n" \ - " META_ID := id [ shift SHIFT ] [ mask MASK ]\n" \ - "\n" \ - "Example: meta(nfmark gt 24)\n" \ - " meta(indev shift 1 eq \"ppp\"\n" \ - " meta(tcindex mask 0xf0 eq 0xf0)\n" \ - " meta(dev eq indev)\n" \ - "\n" \ - "For a list of meta identifiers, use meta(list).\n"); -} - -struct meta_entry { - int id; - char * kind; - char * mask; - char * desc; -} meta_table[] = { -#define TCF_META_ID_SECTION 0 -#define __A(id, name, mask, desc) { TCF_META_ID_##id, name, mask, desc } - __A(SECTION, "Generic", "", ""), - __A(RANDOM, "random", "i", - "Random value (32 bit)"), - __A(LOADAVG_0, "loadavg_1", "i", - "Load average in last minute"), - __A(LOADAVG_1, "loadavg_5", "i", - "Load average in last 5 minutes"), - __A(LOADAVG_2, "loadavg_15", "i", - "Load average in last 15 minutes"), - - __A(SECTION, "Interfaces", "", ""), - __A(DEV, "dev", "iv", - "Device the packet is on"), - __A(SECTION, "Packet attributes", "", ""), - __A(PRIORITY, "priority", "i", - "Priority of packet"), - __A(PROTOCOL, "protocol", "i", - "Link layer protocol"), - __A(PKTTYPE, "pkt_type", "i", - "Packet type (uni|multi|broad|...)cast"), - __A(PKTLEN, "pkt_len", "i", - "Length of packet"), - __A(DATALEN, "data_len", "i", - "Length of data in packet"), - __A(MACLEN, "mac_len", "i", - "Length of link layer header"), - - __A(SECTION, "Netfilter", "", ""), - __A(NFMARK, "nf_mark", "i", - "Netfilter mark"), - __A(NFMARK, "fwmark", "i", - "Alias for nf_mark"), - - __A(SECTION, "Traffic Control", "", ""), - __A(TCINDEX, "tc_index", "i", "TC Index"), - __A(SECTION, "Routing", "", ""), - __A(RTCLASSID, "rt_classid", "i", - "Routing ClassID (cls_route)"), - __A(RTIIF, "rt_iif", "i", - "Incoming interface index"), - - __A(SECTION, "Sockets", "", ""), - __A(SK_FAMILY, "sk_family", "i", "Address family"), - __A(SK_STATE, "sk_state", "i", "State"), - __A(SK_REUSE, "sk_reuse", "i", "Reuse Flag"), - __A(SK_BOUND_IF, "sk_bind_if", "iv", "Bound interface"), - __A(SK_REFCNT, "sk_refcnt", "i", "Reference counter"), - __A(SK_SHUTDOWN, "sk_shutdown", "i", "Shutdown mask"), - __A(SK_PROTO, "sk_proto", "i", "Protocol"), - __A(SK_TYPE, "sk_type", "i", "Type"), - __A(SK_RCVBUF, "sk_rcvbuf", "i", "Receive buffer size"), - __A(SK_RMEM_ALLOC, "sk_rmem", "i", "RMEM"), - __A(SK_WMEM_ALLOC, "sk_wmem", "i", "WMEM"), - __A(SK_OMEM_ALLOC, "sk_omem", "i", "OMEM"), - __A(SK_WMEM_QUEUED, "sk_wmem_queue","i", "WMEM queue"), - __A(SK_SND_QLEN, "sk_snd_queue", "i", "Send queue length"), - __A(SK_RCV_QLEN, "sk_rcv_queue", "i", "Receive queue length"), - __A(SK_ERR_QLEN, "sk_err_queue", "i", "Error queue length"), - __A(SK_FORWARD_ALLOCS, "sk_fwd_alloc", "i", "Forward allocations"), - __A(SK_SNDBUF, "sk_sndbuf", "i", "Send buffer size"), -#undef __A -}; - -static inline int map_type(char k) -{ - switch (k) { - case 'i': return TCF_META_TYPE_INT; - case 'v': return TCF_META_TYPE_VAR; - } - - fprintf(stderr, "BUG: Unknown map character '%c'\n", k); - return INT_MAX; -} - -static struct meta_entry * lookup_meta_entry(struct bstr *kind) -{ - int i; - - for (i = 0; i < (sizeof(meta_table)/sizeof(meta_table[0])); i++) - if (!bstrcmp(kind, meta_table[i].kind) && - meta_table[i].id != 0) - return &meta_table[i]; - - return NULL; -} - -static struct meta_entry * lookup_meta_entry_byid(int id) -{ - int i; - - for (i = 0; i < (sizeof(meta_table)/sizeof(meta_table[0])); i++) - if (meta_table[i].id == id) - return &meta_table[i]; - - return NULL; -} - -static inline void dump_value(struct nlmsghdr *n, int tlv, unsigned long val, - struct tcf_meta_val *hdr) -{ - __u32 t; - - switch (TCF_META_TYPE(hdr->kind)) { - case TCF_META_TYPE_INT: - t = val; - addattr_l(n, MAX_MSG, tlv, &t, sizeof(t)); - break; - - case TCF_META_TYPE_VAR: - if (TCF_META_ID(hdr->kind) == TCF_META_ID_VALUE) { - struct bstr *a = (struct bstr *) val; - addattr_l(n, MAX_MSG, tlv, a->data, a->len); - } - break; - } -} - -static inline int is_compatible(struct tcf_meta_val *what, - struct tcf_meta_val *needed) -{ - char *p; - struct meta_entry *entry; - - entry = lookup_meta_entry_byid(TCF_META_ID(what->kind)); - - if (entry == NULL) - return 0; - - for (p = entry->mask; p; p++) - if (map_type(*p) == TCF_META_TYPE(needed->kind)) - return 1; - - return 0; -} - -static void list_meta_ids(FILE *fd) -{ - int i; - - fprintf(fd, - "--------------------------------------------------------\n" \ - " ID Type Description\n" \ - "--------------------------------------------------------"); - - for (i = 0; i < (sizeof(meta_table)/sizeof(meta_table[0])); i++) { - if (meta_table[i].id == TCF_META_ID_SECTION) { - fprintf(fd, "\n%s:\n", meta_table[i].kind); - } else { - char *p = meta_table[i].mask; - char buf[64] = {0}; - - fprintf(fd, " %-16s ", meta_table[i].kind); - - while (*p) { - int type = map_type(*p); - - switch (type) { - case TCF_META_TYPE_INT: - strcat(buf, "INT"); - break; - - case TCF_META_TYPE_VAR: - strcat(buf, "VAR"); - break; - } - - if (*(++p)) - strcat(buf, ","); - } - - fprintf(fd, "%-10s %s\n", buf, meta_table[i].desc); - } - } - - fprintf(fd, - "--------------------------------------------------------\n"); -} - -#undef TCF_META_ID_SECTION - -#define PARSE_FAILURE ((void *) (-1)) - -#define PARSE_ERR(CARG, FMT, ARGS...) \ - em_parse_error(EINVAL, args, CARG, &meta_ematch_util, FMT ,##ARGS) - -static inline int can_adopt(struct tcf_meta_val *val) -{ - return !!TCF_META_ID(val->kind); -} - -static inline int overwrite_type(struct tcf_meta_val *src, - struct tcf_meta_val *dst) -{ - return (TCF_META_TYPE(dst->kind) << 12) | TCF_META_ID(src->kind); -} - - -static inline struct bstr * -parse_object(struct bstr *args, struct bstr *arg, struct tcf_meta_val *obj, - unsigned long *dst, struct tcf_meta_val *left) -{ - struct meta_entry *entry; - unsigned long num; - struct bstr *a; - - if (arg->quoted) { - obj->kind = TCF_META_TYPE_VAR << 12; - obj->kind |= TCF_META_ID_VALUE; - *dst = (unsigned long) arg; - return bstr_next(arg); - } - - num = bstrtoul(arg); - if (num != LONG_MAX) { - obj->kind = TCF_META_TYPE_INT << 12; - obj->kind |= TCF_META_ID_VALUE; - *dst = (unsigned long) num; - return bstr_next(arg); - } - - entry = lookup_meta_entry(arg); - - if (entry == NULL) { - PARSE_ERR(arg, "meta: unknown meta id\n"); - return PARSE_FAILURE; - } - - obj->kind = entry->id | (map_type(entry->mask[0]) << 12); - - if (left) { - struct tcf_meta_val *right = obj; - - if (TCF_META_TYPE(right->kind) == TCF_META_TYPE(left->kind)) - goto compatible; - - if (can_adopt(left) && !can_adopt(right)) { - if (is_compatible(left, right)) - left->kind = overwrite_type(left, right); - else - goto not_compatible; - } else if (can_adopt(right) && !can_adopt(left)) { - if (is_compatible(right, left)) - right->kind = overwrite_type(right, left); - else - goto not_compatible; - } else if (can_adopt(left) && can_adopt(right)) { - if (is_compatible(left, right)) - left->kind = overwrite_type(left, right); - else if (is_compatible(right, left)) - right->kind = overwrite_type(right, left); - else - goto not_compatible; - } else - goto not_compatible; - } - -compatible: - - a = bstr_next(arg); - - while(a) { - if (!bstrcmp(a, "shift")) { - unsigned long shift; - - if (a->next == NULL) { - PARSE_ERR(a, "meta: missing argument"); - return PARSE_FAILURE; - } - a = bstr_next(a); - - shift = bstrtoul(a); - if (shift == LONG_MAX) { - PARSE_ERR(a, "meta: invalid shift, must " \ - "be numeric"); - return PARSE_FAILURE; - } - - obj->shift = (__u8) shift; - a = bstr_next(a); - } else if (!bstrcmp(a, "mask")) { - unsigned long mask; - - if (a->next == NULL) { - PARSE_ERR(a, "meta: missing argument"); - return PARSE_FAILURE; - } - a = bstr_next(a); - - mask = bstrtoul(a); - if (mask == LONG_MAX) { - PARSE_ERR(a, "meta: invalid mask, must be " \ - "numeric"); - return PARSE_FAILURE; - } - *dst = (unsigned long) mask; - a = bstr_next(a); - } else - break; - } - - return a; - -not_compatible: - PARSE_ERR(arg, "lvalue and rvalue are not compatible."); - return PARSE_FAILURE; -} - -static int meta_parse_eopt(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr, - struct bstr *args) -{ - int opnd; - struct bstr *a; - struct tcf_meta_hdr meta_hdr; - unsigned long lvalue = 0, rvalue = 0; - - memset(&meta_hdr, 0, sizeof(meta_hdr)); - - if (args == NULL) - return PARSE_ERR(args, "meta: missing arguments"); - - if (!bstrcmp(args, "list")) { - list_meta_ids(stderr); - return -1; - } - - a = parse_object(args, args, &meta_hdr.left, &lvalue, NULL); - if (a == PARSE_FAILURE) - return -1; - else if (a == NULL) - return PARSE_ERR(args, "meta: missing operand"); - - if (!bstrcmp(a, "eq")) - opnd = TCF_EM_OPND_EQ; - else if (!bstrcmp(a, "gt")) - opnd = TCF_EM_OPND_GT; - else if (!bstrcmp(a, "lt")) - opnd = TCF_EM_OPND_LT; - else - return PARSE_ERR(a, "meta: invalid operand"); - - meta_hdr.left.op = (__u8) opnd; - - if (a->next == NULL) - return PARSE_ERR(args, "meta: missing rvalue"); - a = bstr_next(a); - - a = parse_object(args, a, &meta_hdr.right, &rvalue, &meta_hdr.left); - if (a == PARSE_FAILURE) - return -1; - else if (a != NULL) - return PARSE_ERR(a, "meta: unexpected trailer"); - - - addraw_l(n, MAX_MSG, hdr, sizeof(*hdr)); - - addattr_l(n, MAX_MSG, TCA_EM_META_HDR, &meta_hdr, sizeof(meta_hdr)); - - if (lvalue) - dump_value(n, TCA_EM_META_LVALUE, lvalue, &meta_hdr.left); - - if (rvalue) - dump_value(n, TCA_EM_META_RVALUE, rvalue, &meta_hdr.right); - - return 0; -} -#undef PARSE_ERR - -static inline void print_binary(FILE *fd, unsigned char *str, int len) -{ - int i; - - for (i = 0; i < len; i++) - if (!isprint(str[i])) - goto binary; - - for (i = 0; i < len; i++) - fprintf(fd, "%c", str[i]); - return; - -binary: - for (i = 0; i < len; i++) - fprintf(fd, "%02x ", str[i]); - - fprintf(fd, "\""); - for (i = 0; i < len; i++) - fprintf(fd, "%c", isprint(str[i]) ? str[i] : '.'); - fprintf(fd, "\""); -} - -static inline int print_value(FILE *fd, int type, struct rtattr *rta) -{ - if (rta == NULL) { - fprintf(stderr, "Missing value TLV\n"); - return -1; - } - - switch(type) { - case TCF_META_TYPE_INT: - if (RTA_PAYLOAD(rta) < sizeof(__u32)) { - fprintf(stderr, "meta int type value TLV " \ - "size mismatch.\n"); - return -1; - } - fprintf(fd, "%d", *(__u32 *) RTA_DATA(rta)); - break; - - case TCF_META_TYPE_VAR: - print_binary(fd, RTA_DATA(rta), RTA_PAYLOAD(rta)); - break; - } - - return 0; -} - -static int print_object(FILE *fd, struct tcf_meta_val *obj, struct rtattr *rta) -{ - int id = TCF_META_ID(obj->kind); - int type = TCF_META_TYPE(obj->kind); - struct meta_entry *entry; - - if (id == TCF_META_ID_VALUE) - return print_value(fd, type, rta); - - entry = lookup_meta_entry_byid(id); - - if (entry == NULL) - fprintf(fd, "[unknown meta id %d]", id); - else - fprintf(fd, "%s", entry->kind); - - if (obj->shift) - fprintf(fd, " shift %d", obj->shift); - - switch (type) { - case TCF_META_TYPE_INT: - if (rta) { - if (RTA_PAYLOAD(rta) < sizeof(__u32)) - goto size_mismatch; - - fprintf(fd, " mask 0x%08x", - *(__u32*) RTA_DATA(rta)); - } - break; - } - - return 0; - -size_mismatch: - fprintf(stderr, "meta int type mask TLV size mismatch\n"); - return -1; -} - - -static int meta_print_eopt(FILE *fd, struct tcf_ematch_hdr *hdr, void *data, - int data_len) -{ - struct rtattr *tb[TCA_EM_META_MAX+1]; - struct tcf_meta_hdr *meta_hdr; - - if (parse_rtattr(tb, TCA_EM_META_MAX, data, data_len) < 0) - return -1; - - if (tb[TCA_EM_META_HDR] == NULL) { - fprintf(stderr, "Missing meta header\n"); - return -1; - } - - if (RTA_PAYLOAD(tb[TCA_EM_META_HDR]) < sizeof(*meta_hdr)) { - fprintf(stderr, "Meta header size mismatch\n"); - return -1; - } - - meta_hdr = RTA_DATA(tb[TCA_EM_META_HDR]); - - if (print_object(fd, &meta_hdr->left, tb[TCA_EM_META_LVALUE]) < 0) - return -1; - - switch (meta_hdr->left.op) { - case TCF_EM_OPND_EQ: - fprintf(fd, " eq "); - break; - case TCF_EM_OPND_LT: - fprintf(fd, " lt "); - break; - case TCF_EM_OPND_GT: - fprintf(fd, " gt "); - break; - } - - return print_object(fd, &meta_hdr->right, tb[TCA_EM_META_RVALUE]); -} - -struct ematch_util meta_ematch_util = { - .kind = "meta", - .kind_num = TCF_EM_META, - .parse_eopt = meta_parse_eopt, - .print_eopt = meta_print_eopt, - .print_usage = meta_print_usage -}; diff --git a/tc/em_nbyte.c b/tc/em_nbyte.c deleted file mode 100644 index e0ed5ba..0000000 --- a/tc/em_nbyte.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * em_nbyte.c N-Byte Ematch - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Thomas Graf <tgraf@suug.ch> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <dlfcn.h> -#include <errno.h> - -#include "m_ematch.h" -#include <linux/tc_ematch/tc_em_nbyte.h> - -extern struct ematch_util nbyte_ematch_util; - -static void nbyte_print_usage(FILE *fd) -{ - fprintf(fd, - "Usage: nbyte(NEEDLE at OFFSET [layer LAYER])\n" \ - "where: NEEDLE := { string | \"c-escape-sequence\" }\n" \ - " OFFSET := int\n" \ - " LAYER := { link | header | next-header | 0..%d }\n" \ - "\n" \ - "Example: nbyte(\"ababa\" at 12 layer 1)\n", - TCF_LAYER_MAX); -} - -static int nbyte_parse_eopt(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr, - struct bstr *args) -{ - struct bstr *a; - struct bstr *needle = args; - unsigned long offset = 0, layer = TCF_LAYER_NETWORK; - int offset_present = 0; - struct tcf_em_nbyte nb; - - memset(&nb, 0, sizeof(nb)); - -#define PARSE_ERR(CARG, FMT, ARGS...) \ - em_parse_error(EINVAL, args, CARG, &nbyte_ematch_util, FMT ,##ARGS) - - if (args == NULL) - return PARSE_ERR(args, "nbyte: missing arguments"); - - if (needle->len <= 0) - return PARSE_ERR(args, "nbyte: needle length is 0"); - - for (a = bstr_next(args); a; a = bstr_next(a)) { - if (!bstrcmp(a, "at")) { - if (a->next == NULL) - return PARSE_ERR(a, "nbyte: missing argument"); - a = bstr_next(a); - - offset = bstrtoul(a); - if (offset == ULONG_MAX) - return PARSE_ERR(a, "nbyte: invalid offset, " \ - "must be numeric"); - - offset_present = 1; - } else if (!bstrcmp(a, "layer")) { - if (a->next == NULL) - return PARSE_ERR(a, "nbyte: missing argument"); - a = bstr_next(a); - - layer = parse_layer(a); - if (layer == INT_MAX) { - layer = bstrtoul(a); - if (layer == ULONG_MAX) - return PARSE_ERR(a, "nbyte: invalid " \ - "layer"); - } - - if (layer > TCF_LAYER_MAX) - return PARSE_ERR(a, "nbyte: illegal layer, " \ - "must be in 0..%d", TCF_LAYER_MAX); - } else - return PARSE_ERR(a, "nbyte: unknown parameter"); - } - - if (offset_present == 0) - return PARSE_ERR(a, "nbyte: offset required"); - - nb.len = needle->len; - nb.layer = (__u8) layer; - nb.off = (__u16) offset; - - addraw_l(n, MAX_MSG, hdr, sizeof(*hdr)); - addraw_l(n, MAX_MSG, &nb, sizeof(nb)); - addraw_l(n, MAX_MSG, needle->data, needle->len); - -#undef PARSE_ERR - return 0; -} - -static int nbyte_print_eopt(FILE *fd, struct tcf_ematch_hdr *hdr, void *data, - int data_len) -{ - int i; - struct tcf_em_nbyte *nb = data; - __u8 *needle; - - if (data_len < sizeof(*nb)) { - fprintf(stderr, "NByte header size mismatch\n"); - return -1; - } - - if (data_len < sizeof(*nb) + nb->len) { - fprintf(stderr, "NByte payload size mismatch\n"); - return -1; - } - - needle = data + sizeof(*nb); - - for (i = 0; i < nb->len; i++) - fprintf(fd, "%02x ", needle[i]); - - fprintf(fd, "\""); - for (i = 0; i < nb->len; i++) - fprintf(fd, "%c", isprint(needle[i]) ? needle[i] : '.'); - fprintf(fd, "\" at %d layer %d", nb->off, nb->layer); - - return 0; -} - -struct ematch_util nbyte_ematch_util = { - .kind = "nbyte", - .kind_num = TCF_EM_NBYTE, - .parse_eopt = nbyte_parse_eopt, - .print_eopt = nbyte_print_eopt, - .print_usage = nbyte_print_usage -}; diff --git a/tc/em_u32.c b/tc/em_u32.c deleted file mode 100644 index b8857f1..0000000 --- a/tc/em_u32.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * em_u32.c U32 Ematch - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Thomas Graf <tgraf@suug.ch> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <dlfcn.h> -#include <errno.h> - -#include "m_ematch.h" - -extern struct ematch_util u32_ematch_util; - -static void u32_print_usage(FILE *fd) -{ - fprintf(fd, - "Usage: u32(ALIGN VALUE MASK at [ nexthdr+ ] OFFSET)\n" \ - "where: ALIGN := { u8 | u16 | u32 }\n" \ - "\n" \ - "Example: u32(u16 0x1122 0xffff at nexthdr+4)\n"); -} - -static int u32_parse_eopt(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr, - struct bstr *args) -{ - struct bstr *a; - int align, nh_len; - unsigned long key, mask, offmask = 0, offset; - struct tc_u32_key u_key; - - memset(&u_key, 0, sizeof(u_key)); - -#define PARSE_ERR(CARG, FMT, ARGS...) \ - em_parse_error(EINVAL, args, CARG, &u32_ematch_util, FMT ,##ARGS) - - if (args == NULL) - return PARSE_ERR(args, "u32: missing arguments"); - - if (!bstrcmp(args, "u8")) - align = 1; - else if (!bstrcmp(args, "u16")) - align = 2; - else if (!bstrcmp(args, "u32")) - align = 4; - else - return PARSE_ERR(args, "u32: invalid alignment"); - - a = bstr_next(args); - if (a == NULL) - return PARSE_ERR(a, "u32: missing key"); - - key = bstrtoul(a); - if (key == ULONG_MAX) - return PARSE_ERR(a, "u32: invalid key, must be numeric"); - - a = bstr_next(a); - if (a == NULL) - return PARSE_ERR(a, "u32: missing mask"); - - mask = bstrtoul(a); - if (mask == ULONG_MAX) - return PARSE_ERR(a, "u32: invalid mask, must be numeric"); - - a = bstr_next(a); - if (a == NULL || bstrcmp(a, "at") != 0) - return PARSE_ERR(a, "u32: missing \"at\""); - - a = bstr_next(a); - if (a == NULL) - return PARSE_ERR(a, "u32: missing offset"); - - nh_len = strlen("nexthdr+"); - if (a->len > nh_len && !memcmp(a->data, "nexthdr+", nh_len)) { - char buf[a->len - nh_len + 1]; - offmask = -1; - memcpy(buf, a->data + nh_len, a->len - nh_len); - offset = strtoul(buf, NULL, 0); - } else if (!bstrcmp(a, "nexthdr+")) { - a = bstr_next(a); - if (a == NULL) - return PARSE_ERR(a, "u32: missing offset"); - offset = bstrtoul(a); - } else - offset = bstrtoul(a); - - if (offset == ULONG_MAX) - return PARSE_ERR(a, "u32: invalid offset"); - - if (a->next) - return PARSE_ERR(a->next, "u32: unexpected trailer"); - - switch (align) { - case 1: - if (key > 0xFF) - return PARSE_ERR(a, "Illegal key (>0xFF)"); - if (mask > 0xFF) - return PARSE_ERR(a, "Illegal mask (>0xFF)"); - - key <<= 24 - ((offset & 3) * 8); - mask <<= 24 - ((offset & 3) * 8); - offset &= ~3; - break; - - case 2: - if (key > 0xFFFF) - return PARSE_ERR(a, "Illegal key (>0xFFFF)"); - if (mask > 0xFFFF) - return PARSE_ERR(a, "Illegal mask (>0xFFFF)"); - - if ((offset & 3) == 0) { - key <<= 16; - mask <<= 16; - } - offset &= ~3; - break; - } - - key = htonl(key); - mask = htonl(mask); - - if (offset % 4) - return PARSE_ERR(a, "u32: invalid offset alignment, " \ - "must be aligned to 4."); - - key &= mask; - - u_key.mask = mask; - u_key.val = key; - u_key.off = offset; - u_key.offmask = offmask; - - addraw_l(n, MAX_MSG, hdr, sizeof(*hdr)); - addraw_l(n, MAX_MSG, &u_key, sizeof(u_key)); - -#undef PARSE_ERR - return 0; -} - -static int u32_print_eopt(FILE *fd, struct tcf_ematch_hdr *hdr, void *data, - int data_len) -{ - struct tc_u32_key *u_key = data; - - if (data_len < sizeof(*u_key)) { - fprintf(stderr, "U32 header size mismatch\n"); - return -1; - } - - fprintf(fd, "%08x/%08x at %s%d", - (unsigned int) ntohl(u_key->val), - (unsigned int) ntohl(u_key->mask), - u_key->offmask ? "nexthdr+" : "", - u_key->off); - - return 0; -} - -struct ematch_util u32_ematch_util = { - .kind = "u32", - .kind_num = TCF_EM_U32, - .parse_eopt = u32_parse_eopt, - .print_eopt = u32_print_eopt, - .print_usage = u32_print_usage -}; diff --git a/tc/emp_ematch.l b/tc/emp_ematch.l deleted file mode 100644 index 09d535d..0000000 --- a/tc/emp_ematch.l +++ /dev/null @@ -1,145 +0,0 @@ -%{ - #include "emp_ematch.yacc.h" - #include "m_ematch.h" - - extern int ematch_argc; - extern char **ematch_argv; - - #define yylval ematch_lval - - #define NEXT_EM_ARG() do { ematch_argc--; ematch_argv++; } while(0); - - #define YY_INPUT(buf, result, max_size) \ - { \ - next: \ - if (ematch_argc <= 0) \ - result = YY_NULL; \ - else if (**ematch_argv == '\0') { \ - NEXT_EM_ARG(); \ - goto next; \ - } else { \ - if (max_size <= strlen(*ematch_argv) + 1) { \ - fprintf(stderr, "match argument too long.\n"); \ - result = YY_NULL; \ - } else { \ - strcpy(buf, *ematch_argv); \ - result = strlen(*ematch_argv) + 1; \ - buf[result-1] = ' '; \ - buf[result] = '\0'; \ - NEXT_EM_ARG(); \ - } \ - } \ - } - - static void __attribute__ ((unused)) yyunput (int c,char *buf_ptr ); - static void __attribute__ ((unused)) yy_push_state (int new_state ); - static void __attribute__ ((unused)) yy_pop_state (void); - static int __attribute__ ((unused)) yy_top_state (void ); - - static char *strbuf; - static unsigned int strbuf_size; - static unsigned int strbuf_index; - - static void strbuf_enlarge(void) - { - strbuf_size += 512; - strbuf = realloc(strbuf, strbuf_size); - } - - static void strbuf_append_char(char c) - { - while (strbuf_index >= strbuf_size) - strbuf_enlarge(); - strbuf[strbuf_index++] = c; - } - - static void strbuf_append_charp(char *s) - { - while (strbuf_index >= strbuf_size) - strbuf_enlarge(); - memcpy(strbuf + strbuf_index, s, strlen(s)); - strbuf_index += strlen(s); - } - -%} - -%x str - -%option 8bit stack warn noyywrap prefix="ematch_" -%% -[ \t\r\n]+ - -\" { - if (strbuf == NULL) { - strbuf_size = 512; - strbuf = calloc(1, strbuf_size); - if (strbuf == NULL) - return ERROR; - } - strbuf_index = 0; - - BEGIN(str); - } - -<str>\" { - BEGIN(INITIAL); - yylval.b = bstr_new(strbuf, strbuf_index); - yylval.b->quoted = 1; - return ATTRIBUTE; - } - -<str>\\[0-7]{1,3} { /* octal escape sequence */ - int res; - - sscanf(yytext + 1, "%o", &res); - if (res > 0xFF) { - fprintf(stderr, "error: octal escape sequence" \ - " out of range\n"); - return ERROR; - } - strbuf_append_char((unsigned char) res); - } - -<str>\\[0-9]+ { /* catch wrong octal escape seq. */ - fprintf(stderr, "error: invalid octale escape sequence\n"); - return ERROR; - } - -<str>\\x[0-9a-fA-F]{1,2} { - int res; - - sscanf(yytext + 2, "%x", &res); - - if (res > 0xFF) { - fprintf(stderr, "error: hexadecimal escape " \ - "sequence out of range\n"); - return ERROR; - } - strbuf_append_char((unsigned char) res); - } - -<str>\\n strbuf_append_char('\n'); -<str>\\r strbuf_append_char('\r'); -<str>\\t strbuf_append_char('\t'); -<str>\\v strbuf_append_char('\v'); -<str>\\b strbuf_append_char('\b'); -<str>\\f strbuf_append_char('\f'); -<str>\\a strbuf_append_char('\a'); - -<str>\\(.|\n) strbuf_append_char(yytext[1]); -<str>[^\\\n\"]+ strbuf_append_charp(yytext); - -[aA][nN][dD] return AND; -[oO][rR] return OR; -[nN][oO][tT] return NOT; -"(" | -")" { - return yylval.i = *yytext; - } -[^ \t\r\n()]+ { - yylval.b = bstr_alloc(yytext); - if (yylval.b == NULL) - return ERROR; - return ATTRIBUTE; - } -%% diff --git a/tc/emp_ematch.y b/tc/emp_ematch.y deleted file mode 100644 index e8d1671..0000000 --- a/tc/emp_ematch.y +++ /dev/null @@ -1,101 +0,0 @@ -%{ - #include <stdio.h> - #include <stdlib.h> - #include <malloc.h> - #include <string.h> - #include "m_ematch.h" -%} - -%locations -%token-table -%error-verbose -%name-prefix="ematch_" - -%union { - unsigned int i; - struct bstr *b; - struct ematch *e; -} - -%{ - extern int ematch_lex(void); - extern void yyerror(char *s); - extern struct ematch *ematch_root; - extern char *ematch_err; -%} - -%token <i> ERROR -%token <b> ATTRIBUTE -%token <i> AND OR NOT -%type <i> invert relation -%type <e> match expr -%type <b> args -%right AND OR -%start input -%% -input: - /* empty */ - | expr - { ematch_root = $1; } - | expr error - { - ematch_root = $1; - YYACCEPT; - } - ; - -expr: - match - { $$ = $1; } - | match relation expr - { - $1->relation = $2; - $1->next = $3; - $$ = $1; - } - ; - -match: - invert ATTRIBUTE '(' args ')' - { - $2->next = $4; - $$ = new_ematch($2, $1); - if ($$ == NULL) - YYABORT; - } - | invert '(' expr ')' - { - $$ = new_ematch(NULL, $1); - if ($$ == NULL) - YYABORT; - $$->child = $3; - } - ; - -args: - ATTRIBUTE - { $$ = $1; } - | ATTRIBUTE args - { $1->next = $2; } - ; - -relation: - AND - { $$ = TCF_EM_REL_AND; } - | OR - { $$ = TCF_EM_REL_OR; } - ; - -invert: - /* empty */ - { $$ = 0; } - | NOT - { $$ = 1; } - ; -%% - - void yyerror(char *s) - { - ematch_err = strdup(s); - } - diff --git a/tc/f_basic.c b/tc/f_basic.c deleted file mode 100644 index 264f358..0000000 --- a/tc/f_basic.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * f_basic.c Basic Classifier - * - * This program is free software; you can u32istribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Thomas Graf <tgraf@suug.ch> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <linux/if.h> - -#include "utils.h" -#include "tc_util.h" -#include "m_ematch.h" - -static void explain(void) -{ - fprintf(stderr, "Usage: ... basic [ match EMATCH_TREE ] [ police POLICE_SPEC ]\n"); - fprintf(stderr, " [ action ACTION_SPEC ] [ classid CLASSID ]\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "Where: SELECTOR := SAMPLE SAMPLE ...\n"); - fprintf(stderr, " FILTERID := X:Y:Z\n"); -} - -static int basic_parse_opt(struct filter_util *qu, char *handle, - int argc, char **argv, struct nlmsghdr *n) -{ - struct tcmsg *t = NLMSG_DATA(n); - struct rtattr *tail; - long h = 0; - - if (argc == 0) - return 0; - - if (handle) { - h = strtol(handle, NULL, 0); - if (h == LONG_MIN || h == LONG_MAX) { - fprintf(stderr, "Illegal handle \"%s\", must be numeric.\n", - handle); - return -1; - } - } - - t->tcm_handle = h; - - tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len)); - addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0); - - while (argc > 0) { - if (matches(*argv, "match") == 0) { - NEXT_ARG(); - if (parse_ematch(&argc, &argv, TCA_BASIC_EMATCHES, n)) { - fprintf(stderr, "Illegal \"ematch\"\n"); - return -1; - } - continue; - } else if (matches(*argv, "classid") == 0 || - strcmp(*argv, "flowid") == 0) { - unsigned handle; - NEXT_ARG(); - if (get_tc_classid(&handle, *argv)) { - fprintf(stderr, "Illegal \"classid\"\n"); - return -1; - } - addattr_l(n, MAX_MSG, TCA_BASIC_CLASSID, &handle, 4); - } else if (matches(*argv, "action") == 0) { - NEXT_ARG(); - if (parse_action(&argc, &argv, TCA_BASIC_ACT, n)) { - fprintf(stderr, "Illegal \"action\"\n"); - return -1; - } - continue; - - } else if (matches(*argv, "police") == 0) { - NEXT_ARG(); - if (parse_police(&argc, &argv, TCA_BASIC_POLICE, n)) { - fprintf(stderr, "Illegal \"police\"\n"); - return -1; - } - continue; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - - tail->rta_len = (((void*)n)+n->nlmsg_len) - (void*)tail; - return 0; -} - -static int basic_print_opt(struct filter_util *qu, FILE *f, - struct rtattr *opt, __u32 handle) -{ - struct rtattr *tb[TCA_BASIC_MAX+1]; - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_BASIC_MAX, opt); - - if (handle) - fprintf(f, "handle 0x%x ", handle); - - if (tb[TCA_BASIC_CLASSID]) { - SPRINT_BUF(b1); - fprintf(f, "flowid %s ", - sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_BASIC_CLASSID]), b1)); - } - - if (tb[TCA_BASIC_EMATCHES]) - print_ematch(f, tb[TCA_BASIC_EMATCHES]); - - if (tb[TCA_BASIC_POLICE]) { - fprintf(f, "\n"); - tc_print_police(f, tb[TCA_BASIC_POLICE]); - } - - if (tb[TCA_BASIC_ACT]) { - tc_print_action(f, tb[TCA_BASIC_ACT]); - } - - return 0; -} - -struct filter_util basic_filter_util = { - .id = "basic", - .parse_fopt = basic_parse_opt, - .print_fopt = basic_print_opt, -}; diff --git a/tc/f_fw.c b/tc/f_fw.c deleted file mode 100644 index 5a56098..0000000 --- a/tc/f_fw.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * f_fw.c FW filter. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <linux/if.h> /* IFNAMSIZ */ -#include "utils.h" -#include "tc_util.h" - -static void explain(void) -{ - fprintf(stderr, "Usage: ... fw [ classid CLASSID ] [ police POLICE_SPEC ]\n"); - fprintf(stderr, " POLICE_SPEC := ... look at TBF\n"); - fprintf(stderr, " CLASSID := X:Y\n"); -} - -#define usage() return(-1) - -static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) -{ - struct tc_police tp; - struct tcmsg *t = NLMSG_DATA(n); - struct rtattr *tail; - - memset(&tp, 0, sizeof(tp)); - - if (handle) { - if (get_u32(&t->tcm_handle, handle, 0)) { - fprintf(stderr, "Illegal \"handle\"\n"); - return -1; - } - } - - if (argc == 0) - return 0; - - tail = NLMSG_TAIL(n); - addattr_l(n, 4096, TCA_OPTIONS, NULL, 0); - - while (argc > 0) { - if (matches(*argv, "classid") == 0 || - matches(*argv, "flowid") == 0) { - unsigned handle; - NEXT_ARG(); - if (get_tc_classid(&handle, *argv)) { - fprintf(stderr, "Illegal \"classid\"\n"); - return -1; - } - addattr_l(n, 4096, TCA_FW_CLASSID, &handle, 4); - } else if (matches(*argv, "police") == 0) { - NEXT_ARG(); - if (parse_police(&argc, &argv, TCA_FW_POLICE, n)) { - fprintf(stderr, "Illegal \"police\"\n"); - return -1; - } - continue; - } else if (matches(*argv, "action") == 0) { - NEXT_ARG(); - if (parse_action(&argc, &argv, TCA_FW_ACT, n)) { - fprintf(stderr, "Illegal fw \"action\"\n"); - return -1; - } - continue; - } else if (strcmp(*argv, "indev") == 0) { - char d[IFNAMSIZ+1]; - memset(d, 0, sizeof (d)); - argc--; - argv++; - if (argc < 1) { - fprintf(stderr, "Illegal indev\n"); - return -1; - } - strncpy(d, *argv, sizeof (d) - 1); - addattr_l(n, MAX_MSG, TCA_FW_INDEV, d, strlen(d) + 1); - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - -static int fw_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle) -{ - struct rtattr *tb[TCA_FW_MAX+1]; - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_FW_MAX, opt); - - if (handle) - fprintf(f, "handle 0x%x ", handle); - - if (tb[TCA_FW_CLASSID]) { - SPRINT_BUF(b1); - fprintf(f, "classid %s ", sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_FW_CLASSID]), b1)); - } - - if (tb[TCA_FW_POLICE]) - tc_print_police(f, tb[TCA_FW_POLICE]); - if (tb[TCA_FW_INDEV]) { - struct rtattr *idev = tb[TCA_FW_INDEV]; - fprintf(f, "input dev %s ",(char *)RTA_DATA(idev)); - } - - if (tb[TCA_FW_ACT]) { - fprintf(f, "\n"); - tc_print_action(f, tb[TCA_FW_ACT]); - } - return 0; -} - -struct filter_util fw_filter_util = { - .id = "fw", - .parse_fopt = fw_parse_opt, - .print_fopt = fw_print_opt, -}; diff --git a/tc/f_route.c b/tc/f_route.c deleted file mode 100644 index a41b9d5..0000000 --- a/tc/f_route.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * f_route.c ROUTE filter. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "rt_names.h" -#include "tc_common.h" -#include "tc_util.h" - -static void explain(void) -{ - fprintf(stderr, "Usage: ... route [ from REALM | fromif TAG ] [ to REALM ]\n"); - fprintf(stderr, " [ flowid CLASSID ] [ police POLICE_SPEC ]\n"); - fprintf(stderr, " POLICE_SPEC := ... look at TBF\n"); - fprintf(stderr, " CLASSID := X:Y\n"); -} - -#define usage() return(-1) - -static int route_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) -{ - struct tc_police tp; - struct tcmsg *t = NLMSG_DATA(n); - struct rtattr *tail; - __u32 fh = 0xFFFF8000; - __u32 order = 0; - - memset(&tp, 0, sizeof(tp)); - - if (handle) { - if (get_u32(&t->tcm_handle, handle, 0)) { - fprintf(stderr, "Illegal \"handle\"\n"); - return -1; - } - } - - if (argc == 0) - return 0; - - tail = NLMSG_TAIL(n); - addattr_l(n, 4096, TCA_OPTIONS, NULL, 0); - - while (argc > 0) { - if (matches(*argv, "to") == 0) { - __u32 id; - NEXT_ARG(); - if (rtnl_rtrealm_a2n(&id, *argv)) { - fprintf(stderr, "Illegal \"to\"\n"); - return -1; - } - addattr_l(n, 4096, TCA_ROUTE4_TO, &id, 4); - fh &= ~0x80FF; - fh |= id&0xFF; - } else if (matches(*argv, "from") == 0) { - __u32 id; - NEXT_ARG(); - if (rtnl_rtrealm_a2n(&id, *argv)) { - fprintf(stderr, "Illegal \"from\"\n"); - return -1; - } - addattr_l(n, 4096, TCA_ROUTE4_FROM, &id, 4); - fh &= 0xFFFF; - fh |= id<<16; - } else if (matches(*argv, "fromif") == 0) { - __u32 id; - NEXT_ARG(); - ll_init_map(&rth); - if ((id=ll_name_to_index(*argv)) <= 0) { - fprintf(stderr, "Illegal \"fromif\"\n"); - return -1; - } - addattr_l(n, 4096, TCA_ROUTE4_IIF, &id, 4); - fh &= 0xFFFF; - fh |= (0x8000|id)<<16; - } else if (matches(*argv, "classid") == 0 || - strcmp(*argv, "flowid") == 0) { - unsigned handle; - NEXT_ARG(); - if (get_tc_classid(&handle, *argv)) { - fprintf(stderr, "Illegal \"classid\"\n"); - return -1; - } - addattr_l(n, 4096, TCA_ROUTE4_CLASSID, &handle, 4); - } else if (matches(*argv, "police") == 0) { - NEXT_ARG(); - if (parse_police(&argc, &argv, TCA_ROUTE4_POLICE, n)) { - fprintf(stderr, "Illegal \"police\"\n"); - return -1; - } - continue; - } else if (matches(*argv, "order") == 0) { - NEXT_ARG(); - if (get_u32(&order, *argv, 0)) { - fprintf(stderr, "Illegal \"order\"\n"); - return -1; - } - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - if (order) { - fh &= ~0x7F00; - fh |= (order<<8)&0x7F00; - } - if (!t->tcm_handle) - t->tcm_handle = fh; - return 0; -} - -static int route_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle) -{ - struct rtattr *tb[TCA_ROUTE4_MAX+1]; - SPRINT_BUF(b1); - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_ROUTE4_MAX, opt); - - if (handle) - fprintf(f, "fh 0x%08x ", handle); - if (handle&0x7F00) - fprintf(f, "order %d ", (handle>>8)&0x7F); - - if (tb[TCA_ROUTE4_CLASSID]) { - SPRINT_BUF(b1); - fprintf(f, "flowid %s ", sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID]), b1)); - } - if (tb[TCA_ROUTE4_TO]) - fprintf(f, "to %s ", rtnl_rtrealm_n2a(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_TO]), b1, sizeof(b1))); - if (tb[TCA_ROUTE4_FROM]) - fprintf(f, "from %s ", rtnl_rtrealm_n2a(*(__u32*)RTA_DATA(tb[TCA_ROUTE4_FROM]), b1, sizeof(b1))); - if (tb[TCA_ROUTE4_IIF]) - fprintf(f, "fromif %s", ll_index_to_name(*(int*)RTA_DATA(tb[TCA_ROUTE4_IIF]))); - if (tb[TCA_ROUTE4_POLICE]) - tc_print_police(f, tb[TCA_ROUTE4_POLICE]); - return 0; -} - -struct filter_util route_filter_util = { - .id = "route", - .parse_fopt = route_parse_opt, - .print_fopt = route_print_opt, -}; diff --git a/tc/f_rsvp.c b/tc/f_rsvp.c deleted file mode 100644 index 13fcf97..0000000 --- a/tc/f_rsvp.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * q_rsvp.c RSVP filter. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "rt_names.h" -#include "utils.h" -#include "tc_util.h" - -static void explain(void) -{ - fprintf(stderr, "Usage: ... rsvp ipproto PROTOCOL session DST[/PORT | GPI ]\n"); - fprintf(stderr, " [ sender SRC[/PORT | GPI ]\n"); - fprintf(stderr, " [ classid CLASSID ] [ police POLICE_SPEC ]\n"); - fprintf(stderr, " [ tunnelid ID ] [ tunnel ID skip NUMBER ]\n"); - fprintf(stderr, "Where: GPI := { flowlabel NUMBER | spi/ah SPI | spi/esp SPI |\n"); - fprintf(stderr, " u{8|16|32} NUMBER mask MASK at OFFSET}\n"); - fprintf(stderr, " POLICE_SPEC := ... look at TBF\n"); - fprintf(stderr, " FILTERID := X:Y\n"); -} - -#define usage() return(-1) - -int get_addr_and_pi(int *argc_p, char ***argv_p, inet_prefix * addr, - struct tc_rsvp_pinfo *pinfo, int dir, int family) -{ - int argc = *argc_p; - char **argv = *argv_p; - char *p = strchr(*argv, '/'); - struct tc_rsvp_gpi *pi = dir ? &pinfo->dpi : &pinfo->spi; - - if (p) { - __u16 tmp; - - if (get_u16(&tmp, p+1, 0)) - return -1; - - if (dir == 0) { - /* Source port: u16 at offset 0 */ - pi->key = htonl(((__u32)tmp)<<16); - pi->mask = htonl(0xFFFF0000); - } else { - /* Destination port: u16 at offset 2 */ - pi->key = htonl(((__u32)tmp)); - pi->mask = htonl(0x0000FFFF); - } - pi->offset = 0; - *p = 0; - } - if (get_addr_1(addr, *argv, family)) - return -1; - if (p) - *p = '/'; - - argc--; argv++; - - if (pi->mask || argc <= 0) - goto done; - - if (strcmp(*argv, "spi/ah") == 0 || - strcmp(*argv, "gpi/ah") == 0) { - __u32 gpi; - NEXT_ARG(); - if (get_u32(&gpi, *argv, 0)) - return -1; - pi->mask = htonl(0xFFFFFFFF); - pi->key = htonl(gpi); - pi->offset = 4; - if (pinfo->protocol == 0) - pinfo->protocol = IPPROTO_AH; - argc--; argv++; - } else if (strcmp(*argv, "spi/esp") == 0 || - strcmp(*argv, "gpi/esp") == 0) { - __u32 gpi; - NEXT_ARG(); - if (get_u32(&gpi, *argv, 0)) - return -1; - pi->mask = htonl(0xFFFFFFFF); - pi->key = htonl(gpi); - pi->offset = 0; - if (pinfo->protocol == 0) - pinfo->protocol = IPPROTO_ESP; - argc--; argv++; - } else if (strcmp(*argv, "flowlabel") == 0) { - __u32 flabel; - NEXT_ARG(); - if (get_u32(&flabel, *argv, 0)) - return -1; - if (family != AF_INET6) - return -1; - pi->mask = htonl(0x000FFFFF); - pi->key = htonl(flabel) & pi->mask; - pi->offset = -40; - argc--; argv++; - } else if (strcmp(*argv, "u32") == 0 || - strcmp(*argv, "u16") == 0 || - strcmp(*argv, "u8") == 0) { - int sz = 1; - __u32 tmp; - __u32 mask = 0xff; - if (strcmp(*argv, "u32") == 0) { - sz = 4; - mask = 0xffff; - } else if (strcmp(*argv, "u16") == 0) { - mask = 0xffffffff; - sz = 2; - } - NEXT_ARG(); - if (get_u32(&tmp, *argv, 0)) - return -1; - argc--; argv++; - if (strcmp(*argv, "mask") == 0) { - NEXT_ARG(); - if (get_u32(&mask, *argv, 16)) - return -1; - argc--; argv++; - } - if (strcmp(*argv, "at") == 0) { - NEXT_ARG(); - if (get_integer(&pi->offset, *argv, 0)) - return -1; - argc--; argv++; - } - if (sz == 1) { - if ((pi->offset & 3) == 0) { - mask <<= 24; - tmp <<= 24; - } else if ((pi->offset & 3) == 1) { - mask <<= 16; - tmp <<= 16; - } else if ((pi->offset & 3) == 3) { - mask <<= 8; - tmp <<= 8; - } - } else if (sz == 2) { - if ((pi->offset & 3) == 0) { - mask <<= 16; - tmp <<= 16; - } - } - pi->offset &= ~3; - pi->mask = htonl(mask); - pi->key = htonl(tmp) & pi->mask; - } - -done: - *argc_p = argc; - *argv_p = argv; - return 0; -} - - -static int rsvp_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) -{ - int family = strcmp(qu->id, "rsvp") == 0 ? AF_INET : AF_INET6; - struct tc_rsvp_pinfo pinfo; - struct tc_police tp; - struct tcmsg *t = NLMSG_DATA(n); - int pinfo_ok = 0; - struct rtattr *tail; - - memset(&pinfo, 0, sizeof(pinfo)); - memset(&tp, 0, sizeof(tp)); - - if (handle) { - if (get_u32(&t->tcm_handle, handle, 0)) { - fprintf(stderr, "Illegal \"handle\"\n"); - return -1; - } - } - - if (argc == 0) - return 0; - - tail = NLMSG_TAIL(n); - addattr_l(n, 4096, TCA_OPTIONS, NULL, 0); - - while (argc > 0) { - if (matches(*argv, "session") == 0) { - inet_prefix addr; - NEXT_ARG(); - if (get_addr_and_pi(&argc, &argv, &addr, &pinfo, 1, family)) { - fprintf(stderr, "Illegal \"session\"\n"); - return -1; - } - addattr_l(n, 4096, TCA_RSVP_DST, &addr.data, addr.bytelen); - if (pinfo.dpi.mask || pinfo.protocol) - pinfo_ok++; - continue; - } else if (matches(*argv, "sender") == 0 || - matches(*argv, "flowspec") == 0) { - inet_prefix addr; - NEXT_ARG(); - if (get_addr_and_pi(&argc, &argv, &addr, &pinfo, 0, family)) { - fprintf(stderr, "Illegal \"sender\"\n"); - return -1; - } - addattr_l(n, 4096, TCA_RSVP_SRC, &addr.data, addr.bytelen); - if (pinfo.spi.mask || pinfo.protocol) - pinfo_ok++; - continue; - } else if (matches("ipproto", *argv) == 0) { - int num; - NEXT_ARG(); - num = inet_proto_a2n(*argv); - if (num < 0) { - fprintf(stderr, "Illegal \"ipproto\"\n"); - return -1; - } - pinfo.protocol = num; - pinfo_ok++; - } else if (matches(*argv, "classid") == 0 || - strcmp(*argv, "flowid") == 0) { - unsigned handle; - NEXT_ARG(); - if (get_tc_classid(&handle, *argv)) { - fprintf(stderr, "Illegal \"classid\"\n"); - return -1; - } - addattr_l(n, 4096, TCA_RSVP_CLASSID, &handle, 4); - } else if (strcmp(*argv, "tunnelid") == 0) { - unsigned tid; - NEXT_ARG(); - if (get_unsigned(&tid, *argv, 0)) { - fprintf(stderr, "Illegal \"tunnelid\"\n"); - return -1; - } - pinfo.tunnelid = tid; - pinfo_ok++; - } else if (strcmp(*argv, "tunnel") == 0) { - unsigned tid; - NEXT_ARG(); - if (get_unsigned(&tid, *argv, 0)) { - fprintf(stderr, "Illegal \"tunnel\"\n"); - return -1; - } - addattr_l(n, 4096, TCA_RSVP_CLASSID, &tid, 4); - NEXT_ARG(); - if (strcmp(*argv, "skip") == 0) { - NEXT_ARG(); - } - if (get_unsigned(&tid, *argv, 0)) { - fprintf(stderr, "Illegal \"skip\"\n"); - return -1; - } - pinfo.tunnelhdr = tid; - pinfo_ok++; - } else if (matches(*argv, "police") == 0) { - NEXT_ARG(); - if (parse_police(&argc, &argv, TCA_RSVP_POLICE, n)) { - fprintf(stderr, "Illegal \"police\"\n"); - return -1; - } - continue; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - - if (pinfo_ok) - addattr_l(n, 4096, TCA_RSVP_PINFO, &pinfo, sizeof(pinfo)); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - -static char * sprint_spi(struct tc_rsvp_gpi *pi, int dir, char *buf) -{ - if (pi->offset == 0) { - if (dir && pi->mask == htonl(0xFFFF)) { - snprintf(buf, SPRINT_BSIZE-1, "/%d", htonl(pi->key)); - return buf; - } - if (!dir && pi->mask == htonl(0xFFFF0000)) { - snprintf(buf, SPRINT_BSIZE-1, "/%d", htonl(pi->key)>>16); - return buf; - } - if (pi->mask == htonl(0xFFFFFFFF)) { - snprintf(buf, SPRINT_BSIZE-1, " spi/esp 0x%08x", htonl(pi->key)); - return buf; - } - } else if (pi->offset == 4 && pi->mask == htonl(0xFFFFFFFF)) { - snprintf(buf, SPRINT_BSIZE-1, " spi/ah 0x%08x", htonl(pi->key)); - return buf; - } else if (pi->offset == -40 && pi->mask == htonl(0x000FFFFF)) { - snprintf(buf, SPRINT_BSIZE-1, " flowlabel 0x%05x", htonl(pi->key)); - return buf; - } - snprintf(buf, SPRINT_BSIZE-1, " u32 0x%08x mask %08x at %d", - htonl(pi->key), htonl(pi->mask), pi->offset); - return buf; -} - -static int rsvp_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle) -{ - int family = strcmp(qu->id, "rsvp") == 0 ? AF_INET : AF_INET6; - struct rtattr *tb[TCA_RSVP_MAX+1]; - struct tc_rsvp_pinfo *pinfo = NULL; - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_RSVP_MAX, opt); - - if (handle) - fprintf(f, "fh 0x%08x ", handle); - - if (tb[TCA_RSVP_PINFO]) { - if (RTA_PAYLOAD(tb[TCA_RSVP_PINFO]) < sizeof(*pinfo)) - return -1; - - pinfo = RTA_DATA(tb[TCA_RSVP_PINFO]); - } - - if (tb[TCA_RSVP_CLASSID]) { - SPRINT_BUF(b1); - if (!pinfo || pinfo->tunnelhdr == 0) - fprintf(f, "flowid %s ", sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_RSVP_CLASSID]), b1)); - else - fprintf(f, "tunnel %d skip %d ", *(__u32*)RTA_DATA(tb[TCA_RSVP_CLASSID]), pinfo->tunnelhdr); - } else if (pinfo && pinfo->tunnelhdr) - fprintf(f, "tunnel [BAD] skip %d ", pinfo->tunnelhdr); - - if (tb[TCA_RSVP_DST]) { - char buf[128]; - fprintf(f, "session "); - if (inet_ntop(family, RTA_DATA(tb[TCA_RSVP_DST]), buf, sizeof(buf)) == 0) - fprintf(f, " [INVALID DADDR] "); - else - fprintf(f, "%s", buf); - if (pinfo && pinfo->dpi.mask) { - SPRINT_BUF(b2); - fprintf(f, "%s ", sprint_spi(&pinfo->dpi, 1, b2)); - } else - fprintf(f, " "); - } else { - if (pinfo && pinfo->dpi.mask) { - SPRINT_BUF(b2); - fprintf(f, "session [NONE]%s ", sprint_spi(&pinfo->dpi, 1, b2)); - } else - fprintf(f, "session NONE "); - } - - if (pinfo && pinfo->protocol) { - SPRINT_BUF(b1); - fprintf(f, "ipproto %s ", inet_proto_n2a(pinfo->protocol, b1, sizeof(b1))); - } - if (pinfo && pinfo->tunnelid) - fprintf(f, "tunnelid %d ", pinfo->tunnelid); - if (tb[TCA_RSVP_SRC]) { - char buf[128]; - fprintf(f, "sender "); - if (inet_ntop(family, RTA_DATA(tb[TCA_RSVP_SRC]), buf, sizeof(buf)) == 0) { - fprintf(f, "[BAD]"); - } else { - fprintf(f, " %s", buf); - } - if (pinfo && pinfo->spi.mask) { - SPRINT_BUF(b2); - fprintf(f, "%s ", sprint_spi(&pinfo->spi, 0, b2)); - } else - fprintf(f, " "); - } else if (pinfo && pinfo->spi.mask) { - SPRINT_BUF(b2); - fprintf(f, "sender [NONE]%s ", sprint_spi(&pinfo->spi, 0, b2)); - } - if (tb[TCA_RSVP_POLICE]) - tc_print_police(f, tb[TCA_RSVP_POLICE]); - return 0; -} - -struct filter_util rsvp_filter_util = { - .id = "rsvp", - .parse_fopt = rsvp_parse_opt, - .print_fopt = rsvp_print_opt, -}; - -struct filter_util rsvp6_filter_util = { - .id = "rsvp6", - .parse_fopt = rsvp_parse_opt, - .print_fopt = rsvp_print_opt, -}; diff --git a/tc/f_tcindex.c b/tc/f_tcindex.c deleted file mode 100644 index 39ac75a..0000000 --- a/tc/f_tcindex.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * f_tcindex.c Traffic control index filter - * - * Written 1998,1999 by Werner Almesberger - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <string.h> -#include <netinet/in.h> - -#include "utils.h" -#include "tc_util.h" - -static void explain(void) -{ - fprintf(stderr," Usage: ... tcindex [ hash SIZE ] [ mask MASK ]" - " [ shift SHIFT ]\n"); - fprintf(stderr," [ pass_on | fall_through ]\n"); - fprintf(stderr," [ classid CLASSID ] " - "[ police POLICE_SPEC ]\n"); -} - - -#define usage() return(-1) - - -static int tcindex_parse_opt(struct filter_util *qu, char *handle, int argc, - char **argv, struct nlmsghdr *n) -{ - struct tcmsg *t = NLMSG_DATA(n); - struct rtattr *tail; - char *end; - - if (handle) { - t->tcm_handle = strtoul(handle,&end,0); - if (*end) { - fprintf(stderr, "Illegal filter ID\n"); - return -1; - } - } - if (!argc) return 0; - tail = NLMSG_TAIL(n); - addattr_l(n,4096,TCA_OPTIONS,NULL,0); - while (argc) { - if (!strcmp(*argv,"hash")) { - int hash; - - NEXT_ARG(); - hash = strtoul(*argv,&end,0); - if (*end || !hash || hash > 0x10000) { - explain(); - return -1; - } - addattr_l(n,4096,TCA_TCINDEX_HASH,&hash,sizeof(hash)); - } - else if (!strcmp(*argv,"mask")) { - __u16 mask; - - NEXT_ARG(); - mask = strtoul(*argv,&end,0); - if (*end) { - explain(); - return -1; - } - addattr_l(n,4096,TCA_TCINDEX_MASK,&mask,sizeof(mask)); - } - else if (!strcmp(*argv,"shift")) { - int shift; - - NEXT_ARG(); - shift = strtoul(*argv,&end,0); - if (*end) { - explain(); - return -1; - } - addattr_l(n,4096,TCA_TCINDEX_SHIFT,&shift, - sizeof(shift)); - } - else if (!strcmp(*argv,"fall_through")) { - int value = 1; - - addattr_l(n,4096,TCA_TCINDEX_FALL_THROUGH,&value, - sizeof(value)); - } - else if (!strcmp(*argv,"pass_on")) { - int value = 0; - - addattr_l(n,4096,TCA_TCINDEX_FALL_THROUGH,&value, - sizeof(value)); - } - else if (!strcmp(*argv,"classid")) { - __u32 handle; - - NEXT_ARG(); - if (get_tc_classid(&handle,*argv)) { - fprintf(stderr, "Illegal \"classid\"\n"); - return -1; - } - addattr_l(n, 4096, TCA_TCINDEX_CLASSID, &handle, 4); - } - else if (!strcmp(*argv,"police")) { - NEXT_ARG(); - if (parse_police(&argc, &argv, TCA_TCINDEX_POLICE, n)) { - fprintf(stderr, "Illegal \"police\"\n"); - return -1; - } - continue; - } - else { - explain(); - return -1; - } - argc--; - argv++; - } - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - - -static int tcindex_print_opt(struct filter_util *qu, FILE *f, - struct rtattr *opt, __u32 handle) -{ - struct rtattr *tb[TCA_TCINDEX_MAX+1]; - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_TCINDEX_MAX, opt); - - if (handle != ~0) fprintf(f,"handle 0x%04x ",handle); - if (tb[TCA_TCINDEX_HASH]) { - __u16 hash; - - if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH]) < sizeof(hash)) - return -1; - hash = *(__u16 *) RTA_DATA(tb[TCA_TCINDEX_HASH]); - fprintf(f,"hash %d ",hash); - } - if (tb[TCA_TCINDEX_MASK]) { - __u16 mask; - - if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK]) < sizeof(mask)) - return -1; - mask = *(__u16 *) RTA_DATA(tb[TCA_TCINDEX_MASK]); - fprintf(f,"mask 0x%04x ",mask); - } - if (tb[TCA_TCINDEX_SHIFT]) { - int shift; - - if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT]) < sizeof(shift)) - return -1; - shift = *(int *) RTA_DATA(tb[TCA_TCINDEX_SHIFT]); - fprintf(f,"shift %d ",shift); - } - if (tb[TCA_TCINDEX_FALL_THROUGH]) { - int fall_through; - - if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH]) < - sizeof(fall_through)) - return -1; - fall_through = *(int *) RTA_DATA(tb[TCA_TCINDEX_FALL_THROUGH]); - fprintf(f,fall_through ? "fall_through " : "pass_on "); - } - if (tb[TCA_TCINDEX_CLASSID]) { - SPRINT_BUF(b1); - fprintf(f, "classid %s ",sprint_tc_classid(*(__u32 *) - RTA_DATA(tb[TCA_TCINDEX_CLASSID]), b1)); - } - if (tb[TCA_TCINDEX_POLICE]) { - fprintf(f, "\n"); - tc_print_police(f, tb[TCA_TCINDEX_POLICE]); - } - return 0; -} - -struct filter_util tcindex_filter_util = { - .id = "tcindex", - .parse_fopt = tcindex_parse_opt, - .print_fopt = tcindex_print_opt, -}; diff --git a/tc/f_u32.c b/tc/f_u32.c deleted file mode 100644 index 9d527fc..0000000 --- a/tc/f_u32.c +++ /dev/null @@ -1,1084 +0,0 @@ -/* - * q_u32.c U32 filter. - * - * This program is free software; you can u32istribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * Match mark added by Catalin(ux aka Dino) BOIE <catab at umbrella.ro> [5 nov 2004] - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <linux/if.h> - -#include "utils.h" -#include "tc_util.h" - -static void explain(void) -{ - fprintf(stderr, "Usage: ... u32 [ match SELECTOR ... ] [ link HTID ] [ classid CLASSID ]\n"); - fprintf(stderr, " [ police POLICE_SPEC ] [ offset OFFSET_SPEC ]\n"); - fprintf(stderr, " [ ht HTID ] [ hashkey HASHKEY_SPEC ]\n"); - fprintf(stderr, " [ sample SAMPLE ]\n"); - fprintf(stderr, "or u32 divisor DIVISOR\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "Where: SELECTOR := SAMPLE SAMPLE ...\n"); - fprintf(stderr, " SAMPLE := { ip | ip6 | udp | tcp | icmp | u{32|16|8} | mark } SAMPLE_ARGS [divisor DIVISOR]\n"); - fprintf(stderr, " FILTERID := X:Y:Z\n"); -} - -#define usage() return(-1) - -int get_u32_handle(__u32 *handle, char *str) -{ - __u32 htid=0, hash=0, nodeid=0; - char *tmp = strchr(str, ':'); - - if (tmp == NULL) { - if (memcmp("0x", str, 2) == 0) - return get_u32(handle, str, 16); - return -1; - } - htid = strtoul(str, &tmp, 16); - if (tmp == str && *str != ':' && *str != 0) - return -1; - if (htid>=0x1000) - return -1; - if (*tmp) { - str = tmp+1; - hash = strtoul(str, &tmp, 16); - if (tmp == str && *str != ':' && *str != 0) - return -1; - if (hash>=0x100) - return -1; - if (*tmp) { - str = tmp+1; - nodeid = strtoul(str, &tmp, 16); - if (tmp == str && *str != 0) - return -1; - if (nodeid>=0x1000) - return -1; - } - } - *handle = (htid<<20)|(hash<<12)|nodeid; - return 0; -} - -char * sprint_u32_handle(__u32 handle, char *buf) -{ - int bsize = SPRINT_BSIZE-1; - __u32 htid = TC_U32_HTID(handle); - __u32 hash = TC_U32_HASH(handle); - __u32 nodeid = TC_U32_NODE(handle); - char *b = buf; - - if (handle == 0) { - snprintf(b, bsize, "none"); - return b; - } - if (htid) { - int l = snprintf(b, bsize, "%x:", htid>>20); - bsize -= l; - b += l; - } - if (nodeid|hash) { - if (hash) { - int l = snprintf(b, bsize, "%x", hash); - bsize -= l; - b += l; - } - if (nodeid) { - int l = snprintf(b, bsize, ":%x", nodeid); - bsize -= l; - b += l; - } - } - if (show_raw) - snprintf(b, bsize, "[%08x] ", handle); - return buf; -} - -static int pack_key(struct tc_u32_sel *sel, __u32 key, __u32 mask, int off, int offmask) -{ - int i; - int hwm = sel->nkeys; - - key &= mask; - - for (i=0; i<hwm; i++) { - if (sel->keys[i].off == off && sel->keys[i].offmask == offmask) { - __u32 intersect = mask&sel->keys[i].mask; - - if ((key^sel->keys[i].val) & intersect) - return -1; - sel->keys[i].val |= key; - sel->keys[i].mask |= mask; - return 0; - } - } - - if (hwm >= 128) - return -1; - if (off % 4) - return -1; - sel->keys[hwm].val = key; - sel->keys[hwm].mask = mask; - sel->keys[hwm].off = off; - sel->keys[hwm].offmask = offmask; - sel->nkeys++; - return 0; -} - -static int pack_key32(struct tc_u32_sel *sel, __u32 key, __u32 mask, int off, int offmask) -{ - key = htonl(key); - mask = htonl(mask); - return pack_key(sel, key, mask, off, offmask); -} - -static int pack_key16(struct tc_u32_sel *sel, __u32 key, __u32 mask, int off, int offmask) -{ - if (key > 0xFFFF || mask > 0xFFFF) - return -1; - - if ((off & 3) == 0) { - key <<= 16; - mask <<= 16; - } - off &= ~3; - key = htonl(key); - mask = htonl(mask); - - return pack_key(sel, key, mask, off, offmask); -} - -static int pack_key8(struct tc_u32_sel *sel, __u32 key, __u32 mask, int off, int offmask) -{ - if (key > 0xFF || mask > 0xFF) - return -1; - - if ((off & 3) == 0) { - key <<= 24; - mask <<= 24; - } else if ((off & 3) == 1) { - key <<= 16; - mask <<= 16; - } else if ((off & 3) == 2) { - key <<= 8; - mask <<= 8; - } - off &= ~3; - key = htonl(key); - mask = htonl(mask); - - return pack_key(sel, key, mask, off, offmask); -} - - -int parse_at(int *argc_p, char ***argv_p, int *off, int *offmask) -{ - int argc = *argc_p; - char **argv = *argv_p; - char *p = *argv; - - if (argc <= 0) - return -1; - - if (strlen(p) > strlen("nexthdr+") && - memcmp(p, "nexthdr+", strlen("nexthdr+")) == 0) { - *offmask = -1; - p += strlen("nexthdr+"); - } else if (matches(*argv, "nexthdr+") == 0) { - NEXT_ARG(); - *offmask = -1; - p = *argv; - } - - if (get_integer(off, p, 0)) - return -1; - argc--; argv++; - - *argc_p = argc; - *argv_p = argv; - return 0; -} - - -static int parse_u32(int *argc_p, char ***argv_p, struct tc_u32_sel *sel, int off, int offmask) -{ - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - __u32 key; - __u32 mask; - - if (argc < 2) - return -1; - - if (get_u32(&key, *argv, 0)) - return -1; - argc--; argv++; - - if (get_u32(&mask, *argv, 16)) - return -1; - argc--; argv++; - - if (argc > 0 && strcmp(argv[0], "at") == 0) { - NEXT_ARG(); - if (parse_at(&argc, &argv, &off, &offmask)) - return -1; - } - - res = pack_key32(sel, key, mask, off, offmask); - *argc_p = argc; - *argv_p = argv; - return res; -} - -static int parse_u16(int *argc_p, char ***argv_p, struct tc_u32_sel *sel, int off, int offmask) -{ - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - __u32 key; - __u32 mask; - - if (argc < 2) - return -1; - - if (get_u32(&key, *argv, 0)) - return -1; - argc--; argv++; - - if (get_u32(&mask, *argv, 16)) - return -1; - argc--; argv++; - - if (argc > 0 && strcmp(argv[0], "at") == 0) { - NEXT_ARG(); - if (parse_at(&argc, &argv, &off, &offmask)) - return -1; - } - res = pack_key16(sel, key, mask, off, offmask); - *argc_p = argc; - *argv_p = argv; - return res; -} - -static int parse_u8(int *argc_p, char ***argv_p, struct tc_u32_sel *sel, int off, int offmask) -{ - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - __u32 key; - __u32 mask; - - if (argc < 2) - return -1; - - if (get_u32(&key, *argv, 0)) - return -1; - argc--; argv++; - - if (get_u32(&mask, *argv, 16)) - return -1; - argc--; argv++; - - if (key > 0xFF || mask > 0xFF) - return -1; - - if (argc > 0 && strcmp(argv[0], "at") == 0) { - NEXT_ARG(); - if (parse_at(&argc, &argv, &off, &offmask)) - return -1; - } - - res = pack_key8(sel, key, mask, off, offmask); - *argc_p = argc; - *argv_p = argv; - return res; -} - -static int parse_ip_addr(int *argc_p, char ***argv_p, struct tc_u32_sel *sel, int off) -{ - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - inet_prefix addr; - __u32 mask; - int offmask = 0; - - if (argc < 1) - return -1; - - if (get_prefix_1(&addr, *argv, AF_INET)) - return -1; - argc--; argv++; - - if (argc > 0 && strcmp(argv[0], "at") == 0) { - NEXT_ARG(); - if (parse_at(&argc, &argv, &off, &offmask)) - return -1; - } - - mask = 0; - if (addr.bitlen) - mask = htonl(0xFFFFFFFF<<(32-addr.bitlen)); - if (pack_key(sel, addr.data[0], mask, off, offmask) < 0) - return -1; - res = 0; - - *argc_p = argc; - *argv_p = argv; - return res; -} - -static int parse_ip6_addr(int *argc_p, char ***argv_p, struct tc_u32_sel *sel, int off) -{ - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - int plen = 128; - int i; - inet_prefix addr; - int offmask = 0; - - if (argc < 1) - return -1; - - if (get_prefix_1(&addr, *argv, AF_INET6)) - return -1; - argc--; argv++; - - if (argc > 0 && strcmp(argv[0], "at") == 0) { - NEXT_ARG(); - if (parse_at(&argc, &argv, &off, &offmask)) - return -1; - } - - plen = addr.bitlen; - for (i=0; i<plen; i+=32) { -// if (((i+31)&~0x1F)<=plen) { - if (((i+31))<=plen) { - if ((res = pack_key(sel, addr.data[i/32], 0xFFFFFFFF, off+4*(i/32), offmask)) < 0) - return -1; - } else if (i<plen) { - __u32 mask = htonl(0xFFFFFFFF<<(32-(plen-i))); - if ((res = pack_key(sel, addr.data[i/32], mask, off+4*(i/32), offmask)) < 0) - return -1; - } - } - res = 0; - - *argc_p = argc; - *argv_p = argv; - return res; -} - -static int parse_ip(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) -{ - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - - if (argc < 2) - return -1; - - if (strcmp(*argv, "src") == 0) { - NEXT_ARG(); - res = parse_ip_addr(&argc, &argv, sel, 12); - goto done; - } - if (strcmp(*argv, "dst") == 0) { - NEXT_ARG(); - res = parse_ip_addr(&argc, &argv, sel, 16); - goto done; - } - if (strcmp(*argv, "tos") == 0 || - matches(*argv, "dsfield") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 1, 0); - goto done; - } - if (strcmp(*argv, "ihl") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 0, 0); - goto done; - } - if (strcmp(*argv, "protocol") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 9, 0); - goto done; - } - if (matches(*argv, "precedence") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 1, 0); - goto done; - } - if (strcmp(*argv, "nofrag") == 0) { - argc--; argv++; - res = pack_key16(sel, 0, 0x3FFF, 6, 0); - goto done; - } - if (strcmp(*argv, "firstfrag") == 0) { - argc--; argv++; - res = pack_key16(sel, 0, 0x1FFF, 6, 0); - goto done; - } - if (strcmp(*argv, "df") == 0) { - argc--; argv++; - res = pack_key16(sel, 0x4000, 0x4000, 6, 0); - goto done; - } - if (strcmp(*argv, "mf") == 0) { - argc--; argv++; - res = pack_key16(sel, 0x2000, 0x2000, 6, 0); - goto done; - } - if (strcmp(*argv, "dport") == 0) { - NEXT_ARG(); - res = parse_u16(&argc, &argv, sel, 22, 0); - goto done; - } - if (strcmp(*argv, "sport") == 0) { - NEXT_ARG(); - res = parse_u16(&argc, &argv, sel, 20, 0); - goto done; - } - if (strcmp(*argv, "icmp_type") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 20, 0); - goto done; - } - if (strcmp(*argv, "icmp_code") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 20, 1); - goto done; - } - return -1; - -done: - *argc_p = argc; - *argv_p = argv; - return res; -} - -static int parse_ip6(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) -{ - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - - if (argc < 2) - return -1; - - if (strcmp(*argv, "src") == 0) { - NEXT_ARG(); - res = parse_ip6_addr(&argc, &argv, sel, 8); - goto done; - } - if (strcmp(*argv, "dst") == 0) { - NEXT_ARG(); - res = parse_ip6_addr(&argc, &argv, sel, 24); - goto done; - } - if (strcmp(*argv, "priority") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 4, 0); - goto done; - } - if (strcmp(*argv, "protocol") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 6, 0); - goto done; - } - if (strcmp(*argv, "flowlabel") == 0) { - NEXT_ARG(); - res = parse_u32(&argc, &argv, sel, 0, 0); - goto done; - } - if (strcmp(*argv, "dport") == 0) { - NEXT_ARG(); - res = parse_u16(&argc, &argv, sel, 42, 0); - goto done; - } - if (strcmp(*argv, "sport") == 0) { - NEXT_ARG(); - res = parse_u16(&argc, &argv, sel, 40, 0); - goto done; - } - if (strcmp(*argv, "icmp_type") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 40, 0); - goto done; - } - if (strcmp(*argv, "icmp_code") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 41, 1); - goto done; - } - return -1; - -done: - *argc_p = argc; - *argv_p = argv; - return res; -} - -#define parse_tcp parse_udp -static int parse_udp(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) -{ - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - - if (argc < 2) - return -1; - - if (strcmp(*argv, "src") == 0) { - NEXT_ARG(); - res = parse_u16(&argc, &argv, sel, 0, -1); - goto done; - } - if (strcmp(*argv, "dst") == 0) { - NEXT_ARG(); - res = parse_u16(&argc, &argv, sel, 2, -1); - goto done; - } - return -1; - -done: - *argc_p = argc; - *argv_p = argv; - return res; -} - -static int parse_icmp(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) -{ - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - - if (argc < 2) - return -1; - - if (strcmp(*argv, "type") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 0, -1); - goto done; - } - if (strcmp(*argv, "code") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 1, -1); - goto done; - } - return -1; - -done: - *argc_p = argc; - *argv_p = argv; - return res; -} - -static int parse_mark(int *argc_p, char ***argv_p, struct nlmsghdr *n) -{ - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - struct tc_u32_mark mark; - - if (argc <= 1) - return -1; - - if (get_u32(&mark.val, *argv, 0)) { - fprintf(stderr, "Illegal \"mark\" value\n"); - return -1; - } - NEXT_ARG(); - - if (get_u32(&mark.mask, *argv, 0)) { - fprintf(stderr, "Illegal \"mark\" mask\n"); - return -1; - } - NEXT_ARG(); - - if ((mark.val & mark.mask) != mark.val) { - fprintf(stderr, "Illegal \"mark\" (impossible combination)\n"); - return -1; - } - - addattr_l(n, MAX_MSG, TCA_U32_MARK, &mark, sizeof(mark)); - res = 0; - - *argc_p = argc; - *argv_p = argv; - return res; -} - -static int parse_selector(int *argc_p, char ***argv_p, struct tc_u32_sel *sel, struct nlmsghdr *n) -{ - int argc = *argc_p; - char **argv = *argv_p; - int res = -1; - - if (argc <= 0) - return -1; - - if (matches(*argv, "u32") == 0) { - NEXT_ARG(); - res = parse_u32(&argc, &argv, sel, 0, 0); - goto done; - } - if (matches(*argv, "u16") == 0) { - NEXT_ARG(); - res = parse_u16(&argc, &argv, sel, 0, 0); - goto done; - } - if (matches(*argv, "u8") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, sel, 0, 0); - goto done; - } - if (matches(*argv, "ip") == 0) { - NEXT_ARG(); - res = parse_ip(&argc, &argv, sel); - goto done; - } - if (matches(*argv, "ip6") == 0) { - NEXT_ARG(); - res = parse_ip6(&argc, &argv, sel); - goto done; - } - if (matches(*argv, "udp") == 0) { - NEXT_ARG(); - res = parse_udp(&argc, &argv, sel); - goto done; - } - if (matches(*argv, "tcp") == 0) { - NEXT_ARG(); - res = parse_tcp(&argc, &argv, sel); - goto done; - } - if (matches(*argv, "icmp") == 0) { - NEXT_ARG(); - res = parse_icmp(&argc, &argv, sel); - goto done; - } - if (matches(*argv, "mark") == 0) { - NEXT_ARG(); - res = parse_mark(&argc, &argv, n); - goto done; - } - - return -1; - -done: - *argc_p = argc; - *argv_p = argv; - return res; -} - -static int parse_offset(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) -{ - int argc = *argc_p; - char **argv = *argv_p; - - while (argc > 0) { - if (matches(*argv, "plus") == 0) { - int off; - NEXT_ARG(); - if (get_integer(&off, *argv, 0)) - return -1; - sel->off = off; - sel->flags |= TC_U32_OFFSET; - } else if (matches(*argv, "at") == 0) { - int off; - NEXT_ARG(); - if (get_integer(&off, *argv, 0)) - return -1; - sel->offoff = off; - if (off%2) { - fprintf(stderr, "offset \"at\" must be even\n"); - return -1; - } - sel->flags |= TC_U32_VAROFFSET; - } else if (matches(*argv, "mask") == 0) { - __u16 mask; - NEXT_ARG(); - if (get_u16(&mask, *argv, 16)) - return -1; - sel->offmask = htons(mask); - sel->flags |= TC_U32_VAROFFSET; - } else if (matches(*argv, "shift") == 0) { - int shift; - NEXT_ARG(); - if (get_integer(&shift, *argv, 0)) - return -1; - sel->offshift = shift; - sel->flags |= TC_U32_VAROFFSET; - } else if (matches(*argv, "eat") == 0) { - sel->flags |= TC_U32_EAT; - } else { - break; - } - argc--; argv++; - } - - *argc_p = argc; - *argv_p = argv; - return 0; -} - -static int parse_hashkey(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) -{ - int argc = *argc_p; - char **argv = *argv_p; - - while (argc > 0) { - if (matches(*argv, "mask") == 0) { - __u32 mask; - NEXT_ARG(); - if (get_u32(&mask, *argv, 16)) - return -1; - sel->hmask = htonl(mask); - } else if (matches(*argv, "at") == 0) { - int num; - NEXT_ARG(); - if (get_integer(&num, *argv, 0)) - return -1; - if (num%4) - return -1; - sel->hoff = num; - } else { - break; - } - argc--; argv++; - } - - *argc_p = argc; - *argv_p = argv; - return 0; -} - -static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) -{ - struct { - struct tc_u32_sel sel; - struct tc_u32_key keys[128]; - } sel; - struct tcmsg *t = NLMSG_DATA(n); - struct rtattr *tail; - int sel_ok = 0; - int sample_ok = 0; - __u32 htid = 0; - __u32 order = 0; - - memset(&sel, 0, sizeof(sel)); - - if (handle && get_u32_handle(&t->tcm_handle, handle)) { - fprintf(stderr, "Illegal filter ID\n"); - return -1; - } - - if (argc == 0) - return 0; - - tail = NLMSG_TAIL(n); - addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0); - - while (argc > 0) { - if (matches(*argv, "match") == 0) { - NEXT_ARG(); - if (parse_selector(&argc, &argv, &sel.sel, n)) { - fprintf(stderr, "Illegal \"match\"\n"); - return -1; - } - sel_ok++; - continue; - } else if (matches(*argv, "offset") == 0) { - NEXT_ARG(); - if (parse_offset(&argc, &argv, &sel.sel)) { - fprintf(stderr, "Illegal \"offset\"\n"); - return -1; - } - continue; - } else if (matches(*argv, "hashkey") == 0) { - NEXT_ARG(); - if (parse_hashkey(&argc, &argv, &sel.sel)) { - fprintf(stderr, "Illegal \"hashkey\"\n"); - return -1; - } - continue; - } else if (matches(*argv, "classid") == 0 || - strcmp(*argv, "flowid") == 0) { - unsigned handle; - NEXT_ARG(); - if (get_tc_classid(&handle, *argv)) { - fprintf(stderr, "Illegal \"classid\"\n"); - return -1; - } - addattr_l(n, MAX_MSG, TCA_U32_CLASSID, &handle, 4); - sel.sel.flags |= TC_U32_TERMINAL; - } else if (matches(*argv, "divisor") == 0) { - unsigned divisor; - NEXT_ARG(); - if (get_unsigned(&divisor, *argv, 0) || - divisor == 0 || - divisor > 0x100 || ((divisor - 1) & divisor)) { - fprintf(stderr, "Illegal \"divisor\"\n"); - return -1; - } - addattr_l(n, MAX_MSG, TCA_U32_DIVISOR, &divisor, 4); - } else if (matches(*argv, "order") == 0) { - NEXT_ARG(); - if (get_u32(&order, *argv, 0)) { - fprintf(stderr, "Illegal \"order\"\n"); - return -1; - } - } else if (strcmp(*argv, "link") == 0) { - unsigned handle; - NEXT_ARG(); - if (get_u32_handle(&handle, *argv)) { - fprintf(stderr, "Illegal \"link\"\n"); - return -1; - } - if (handle && TC_U32_NODE(handle)) { - fprintf(stderr, "\"link\" must be a hash table.\n"); - return -1; - } - addattr_l(n, MAX_MSG, TCA_U32_LINK, &handle, 4); - } else if (strcmp(*argv, "ht") == 0) { - unsigned handle; - NEXT_ARG(); - if (get_u32_handle(&handle, *argv)) { - fprintf(stderr, "Illegal \"ht\"\n"); - return -1; - } - if (handle && TC_U32_NODE(handle)) { - fprintf(stderr, "\"ht\" must be a hash table.\n"); - return -1; - } - if (sample_ok) - htid = (htid&0xFF000)|(handle&0xFFF00000); - else - htid = (handle&0xFFFFF000); - } else if (strcmp(*argv, "sample") == 0) { - __u32 hash; - unsigned divisor = 0x100; - - struct { - struct tc_u32_sel sel; - struct tc_u32_key keys[4]; - } sel2; - memset(&sel2, 0, sizeof(sel2)); - NEXT_ARG(); - if (parse_selector(&argc, &argv, &sel2.sel, n)) { - fprintf(stderr, "Illegal \"sample\"\n"); - return -1; - } - if (sel2.sel.nkeys != 1) { - fprintf(stderr, "\"sample\" must contain exactly ONE key.\n"); - return -1; - } - if (*argv != 0 && strcmp(*argv, "divisor") == 0) { - NEXT_ARG(); - if (get_unsigned(&divisor, *argv, 0) || divisor == 0 || - divisor > 0x100 || ((divisor - 1) & divisor)) { - fprintf(stderr, "Illegal sample \"divisor\"\n"); - return -1; - } - NEXT_ARG(); - } - hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask; - hash ^= hash>>16; - hash ^= hash>>8; - htid = ((hash%divisor)<<12)|(htid&0xFFF00000); - sample_ok = 1; - continue; - } else if (strcmp(*argv, "indev") == 0) { - char ind[IFNAMSIZ + 1]; - memset(ind, 0, sizeof (ind)); - argc--; - argv++; - if (argc < 1) { - fprintf(stderr, "Illegal indev\n"); - return -1; - } - strncpy(ind, *argv, sizeof (ind) - 1); - addattr_l(n, MAX_MSG, TCA_U32_INDEV, ind, strlen(ind) + 1); - - } else if (matches(*argv, "action") == 0) { - NEXT_ARG(); - if (parse_action(&argc, &argv, TCA_U32_ACT, n)) { - fprintf(stderr, "Illegal \"action\"\n"); - return -1; - } - continue; - - } else if (matches(*argv, "police") == 0) { - NEXT_ARG(); - if (parse_police(&argc, &argv, TCA_U32_POLICE, n)) { - fprintf(stderr, "Illegal \"police\"\n"); - return -1; - } - continue; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - - if (order) { - if (TC_U32_NODE(t->tcm_handle) && order != TC_U32_NODE(t->tcm_handle)) { - fprintf(stderr, "\"order\" contradicts \"handle\"\n"); - return -1; - } - t->tcm_handle |= order; - } - - if (htid) - addattr_l(n, MAX_MSG, TCA_U32_HASH, &htid, 4); - if (sel_ok) - addattr_l(n, MAX_MSG, TCA_U32_SEL, &sel, sizeof(sel.sel)+sel.sel.nkeys*sizeof(struct tc_u32_key)); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - -static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle) -{ - struct rtattr *tb[TCA_U32_MAX+1]; - struct tc_u32_sel *sel = NULL; - struct tc_u32_pcnt *pf = NULL; - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_U32_MAX, opt); - - if (handle) { - SPRINT_BUF(b1); - fprintf(f, "fh %s ", sprint_u32_handle(handle, b1)); - } - if (TC_U32_NODE(handle)) { - fprintf(f, "order %d ", TC_U32_NODE(handle)); - } - - if (tb[TCA_U32_SEL]) { - if (RTA_PAYLOAD(tb[TCA_U32_SEL]) < sizeof(*sel)) - return -1; - - sel = RTA_DATA(tb[TCA_U32_SEL]); - } - - if (tb[TCA_U32_DIVISOR]) { - fprintf(f, "ht divisor %d ", *(__u32*)RTA_DATA(tb[TCA_U32_DIVISOR])); - } else if (tb[TCA_U32_HASH]) { - __u32 htid = *(__u32*)RTA_DATA(tb[TCA_U32_HASH]); - fprintf(f, "key ht %x bkt %x ", TC_U32_USERHTID(htid), TC_U32_HASH(htid)); - } else { - fprintf(f, "??? "); - } - if (tb[TCA_U32_CLASSID]) { - SPRINT_BUF(b1); - fprintf(f, "%sflowid %s ", - !sel || !(sel->flags&TC_U32_TERMINAL) ? "*" : "", - sprint_tc_classid(*(__u32*)RTA_DATA(tb[TCA_U32_CLASSID]), b1)); - } else if (sel && sel->flags&TC_U32_TERMINAL) { - fprintf(f, "terminal flowid ??? "); - } - if (tb[TCA_U32_LINK]) { - SPRINT_BUF(b1); - fprintf(f, "link %s ", sprint_u32_handle(*(__u32*)RTA_DATA(tb[TCA_U32_LINK]), b1)); - } - - if (tb[TCA_U32_PCNT]) { - if (RTA_PAYLOAD(tb[TCA_U32_PCNT]) < sizeof(*pf)) { - fprintf(f, "Broken perf counters \n"); - return -1; - } - pf = RTA_DATA(tb[TCA_U32_PCNT]); - } - - if (sel && show_stats && NULL != pf) - fprintf(f, " (rule hit %llu success %llu)", - (unsigned long long) pf->rcnt, - (unsigned long long) pf->rhit); - - if (tb[TCA_U32_MARK]) { - struct tc_u32_mark *mark = RTA_DATA(tb[TCA_U32_MARK]); - if (RTA_PAYLOAD(tb[TCA_U32_MARK]) < sizeof(*mark)) { - fprintf(f, "\n Invalid mark (kernel&iproute2 mismatch)\n"); - } else { - fprintf(f, "\n mark 0x%04x 0x%04x (success %d)", - mark->val, mark->mask, mark->success); - } - } - - if (sel) { - int i; - struct tc_u32_key *key = sel->keys; - if (sel->nkeys) { - for (i=0; i<sel->nkeys; i++, key++) { - fprintf(f, "\n match %08x/%08x at %s%d", - (unsigned int)ntohl(key->val), - (unsigned int)ntohl(key->mask), - key->offmask ? "nexthdr+" : "", - key->off); - if (show_stats && NULL != pf) - fprintf(f, " (success %lld ) ", - (unsigned long long) pf->kcnts[i]); - } - } - - if (sel->flags&(TC_U32_VAROFFSET|TC_U32_OFFSET)) { - fprintf(f, "\n offset "); - if (sel->flags&TC_U32_VAROFFSET) - fprintf(f, "%04x>>%d at %d ", ntohs(sel->offmask), sel->offshift, sel->offoff); - if (sel->off) - fprintf(f, "plus %d ", sel->off); - } - if (sel->flags&TC_U32_EAT) - fprintf(f, " eat "); - - if (sel->hmask) { - fprintf(f, "\n hash mask %08x at %d ", - (unsigned int)htonl(sel->hmask), sel->hoff); - } - } - - if (tb[TCA_U32_POLICE]) { - fprintf(f, "\n"); - tc_print_police(f, tb[TCA_U32_POLICE]); - } - if (tb[TCA_U32_INDEV]) { - struct rtattr *idev = tb[TCA_U32_INDEV]; - fprintf(f, "\n input dev %s\n", (char *) RTA_DATA(idev)); - } - if (tb[TCA_U32_ACT]) { - tc_print_action(f, tb[TCA_U32_ACT]); - } - - return 0; -} - -struct filter_util u32_filter_util = { - .id = "u32", - .parse_fopt = u32_parse_opt, - .print_fopt = u32_print_opt, -}; diff --git a/tc/m_action.c b/tc/m_action.c deleted file mode 100644 index 2d2b0ed..0000000 --- a/tc/m_action.c +++ /dev/null @@ -1,608 +0,0 @@ -/* - * m_action.c Action Management - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim (hadi@cyberus.ca) - * - * TODO: - * - parse to be passed a filedescriptor for logging purposes - * -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <dlfcn.h> - -#include "utils.h" -#include "tc_common.h" -#include "tc_util.h" - -static struct action_util * action_list; -#ifdef CONFIG_GACT -int gact_ld = 0 ; //fuckin backward compatibility -#endif -int batch_c = 0; -int tab_flush = 0; - -void act_usage(void) -{ - fprintf (stderr, "action usage improper\n"); -} - -static int print_noaopt(struct action_util *au, FILE *f, struct rtattr *opt) -{ - if (opt && RTA_PAYLOAD(opt)) - fprintf(f, "[Unknown action, optlen=%u] ", - (unsigned) RTA_PAYLOAD(opt)); - return 0; -} - -static int parse_noaopt(struct action_util *au, int *argc_p, char ***argv_p, int code, struct nlmsghdr *n) -{ - int argc = *argc_p; - char **argv = *argv_p; - - if (argc) { - fprintf(stderr, "Unknown action \"%s\", hence option \"%s\" is unparsable\n", au->id, *argv); - } else { - fprintf(stderr, "Unknown action \"%s\"\n", au->id); - } - return -1; -} - -struct action_util *get_action_kind(char *str) -{ - static void *aBODY; - void *dlh; - char buf[256]; - struct action_util *a; -#ifdef CONFIG_GACT - int looked4gact = 0; -restart_s: -#endif - for (a = action_list; a; a = a->next) { - if (strcmp(a->id, str) == 0) - return a; - } - - snprintf(buf, sizeof(buf), "m_%s.so", str); - dlh = dlopen(buf, RTLD_LAZY); - if (dlh == NULL) { - dlh = aBODY; - if (dlh == NULL) { - dlh = aBODY = dlopen(NULL, RTLD_LAZY); - if (dlh == NULL) - goto noexist; - } - } - - snprintf(buf, sizeof(buf), "%s_action_util", str); - a = dlsym(dlh, buf); - if (a == NULL) - goto noexist; - -reg: - a->next = action_list; - action_list = a; - return a; - -noexist: -#ifdef CONFIG_GACT - if (!looked4gact) { - looked4gact = 1; - strcpy(str,"gact"); - goto restart_s; - } -#endif - a = malloc(sizeof(*a)); - if (a) { - memset(a, 0, sizeof(*a)); - strncpy(a->id, "noact", 15); - a->parse_aopt = parse_noaopt; - a->print_aopt = print_noaopt; - goto reg; - } - return a; -} - -int -new_cmd(char **argv) -{ - if ((matches(*argv, "change") == 0) || - (matches(*argv, "replace") == 0)|| - (matches(*argv, "delete") == 0)|| - (matches(*argv, "add") == 0)) - return 1; - - return 0; - -} - -int -parse_action(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) -{ - int argc = *argc_p; - char **argv = *argv_p; - struct rtattr *tail, *tail2; - char k[16]; - int ok = 0; - int eap = 0; /* expect action parameters */ - - int ret = 0; - int prio = 0; - - if (argc <= 0) - return -1; - - tail = tail2 = NLMSG_TAIL(n); - - addattr_l(n, MAX_MSG, tca_id, NULL, 0); - - while (argc > 0) { - - memset(k, 0, sizeof (k)); - - if (strcmp(*argv, "action") == 0 ) { - argc--; - argv++; - eap = 1; -#ifdef CONFIG_GACT - if (!gact_ld) { - get_action_kind("gact"); - } -#endif - continue; - } else if (strcmp(*argv, "help") == 0) { - return -1; - } else if (new_cmd(argv)) { - goto done0; - } else { - struct action_util *a = NULL; - strncpy(k, *argv, sizeof (k) - 1); - eap = 0; - if (argc > 0 ) { - a = get_action_kind(k); - } else { -done0: - if (ok) - break; - else - goto done; - } - - if (NULL == a) { - goto bad_val; - } - - tail = NLMSG_TAIL(n); - addattr_l(n, MAX_MSG, ++prio, NULL, 0); - addattr_l(n, MAX_MSG, TCA_ACT_KIND, k, strlen(k) + 1); - - ret = a->parse_aopt(a,&argc, &argv, TCA_ACT_OPTIONS, n); - - if (ret < 0) { - fprintf(stderr,"bad action parsing\n"); - goto bad_val; - } - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - ok++; - } - - } - - if (eap > 0) { - fprintf(stderr,"bad action empty %d\n",eap); - goto bad_val; - } - - tail2->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail2; - -done: - *argc_p = argc; - *argv_p = argv; - return 0; -bad_val: - /* no need to undo things, returning from here should - * cause enough pain */ - fprintf(stderr, "parse_action: bad value (%d:%s)!\n",argc,*argv); - return -1; -} - -int -tc_print_one_action(FILE * f, struct rtattr *arg) -{ - - struct rtattr *tb[TCA_ACT_MAX + 1]; - int err = 0; - struct action_util *a = NULL; - - if (arg == NULL) - return -1; - - parse_rtattr_nested(tb, TCA_ACT_MAX, arg); - if (tb[TCA_ACT_KIND] == NULL) { - fprintf(stderr, "NULL Action!\n"); - return -1; - } - - - a = get_action_kind(RTA_DATA(tb[TCA_ACT_KIND])); - if (NULL == a) - return err; - - if (tab_flush) { - fprintf(f," %s \n", a->id); - tab_flush = 0; - return 0; - } - - err = a->print_aopt(a,f,tb[TCA_ACT_OPTIONS]); - - - if (0 > err) - return err; - - if (show_stats && tb[TCA_ACT_STATS]) { - fprintf(f, "\tAction statistics:\n"); - print_tcstats2_attr(f, tb[TCA_ACT_STATS], "\t", NULL); - fprintf(f, "\n"); - } - - return 0; -} - -int -tc_print_action(FILE * f, const struct rtattr *arg) -{ - - int i; - struct rtattr *tb[TCA_ACT_MAX_PRIO + 1]; - - if (arg == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_ACT_MAX_PRIO, arg); - - if (tab_flush && NULL != tb[0] && NULL == tb[1]) { - int ret = tc_print_one_action(f, tb[0]); - return ret; - } - - for (i = 0; i < TCA_ACT_MAX_PRIO; i++) { - if (tb[i]) { - fprintf(f, "\n\taction order %d: ", i + batch_c); - if (0 > tc_print_one_action(f, tb[i])) { - fprintf(f, "Error printing action\n"); - } - } - - } - - batch_c+=TCA_ACT_MAX_PRIO ; - return 0; -} - -static int do_print_action(const struct sockaddr_nl *who, - struct nlmsghdr *n, - void *arg) -{ - FILE *fp = (FILE*)arg; - struct tcamsg *t = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr * tb[TCAA_MAX+1]; - - len -= NLMSG_LENGTH(sizeof(*t)); - - if (len < 0) { - fprintf(stderr, "Wrong len %d\n", len); - return -1; - } - - parse_rtattr(tb, TCAA_MAX, TA_RTA(t), len); - - if (NULL == tb[TCA_ACT_TAB]) { - if (n->nlmsg_type != RTM_GETACTION) - fprintf(stderr, "do_print_action: NULL kind\n"); - return -1; - } - - if (n->nlmsg_type == RTM_DELACTION) { - if (n->nlmsg_flags & NLM_F_ROOT) { - fprintf(fp, "Flushed table "); - tab_flush = 1; - } else { - fprintf(fp, "deleted action "); - } - } - - if (n->nlmsg_type == RTM_NEWACTION) - fprintf(fp, "Added action "); - tc_print_action(fp, tb[TCA_ACT_TAB]); - - return 0; -} - -int tc_action_gd(int cmd, unsigned flags, int *argc_p, char ***argv_p) -{ - char k[16]; - struct action_util *a = NULL; - int argc = *argc_p; - char **argv = *argv_p; - int prio = 0; - int ret = 0; - __u32 i; - struct sockaddr_nl nladdr; - struct rtattr *tail; - struct rtattr *tail2; - struct nlmsghdr *ans = NULL; - - struct { - struct nlmsghdr n; - struct tcamsg t; - char buf[MAX_MSG]; - } req; - - req.t.tca_family = AF_UNSPEC; - - memset(&req, 0, sizeof(req)); - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|flags; - req.n.nlmsg_type = cmd; - argc -=1; - argv +=1; - - - tail = NLMSG_TAIL(&req.n); - addattr_l(&req.n, MAX_MSG, TCA_ACT_TAB, NULL, 0); - - while (argc > 0) { - if (strcmp(*argv, "action") == 0 ) { - argc--; - argv++; - continue; - } else if (strcmp(*argv, "help") == 0) { - return -1; - } - - strncpy(k, *argv, sizeof (k) - 1); - a = get_action_kind(k); - if (NULL == a) { - fprintf(stderr, "Error: non existent action: %s\n",k); - ret = -1; - goto bad_val; - } - if (strcmp(a->id, k) != 0) { - fprintf(stderr, "Error: non existent action: %s\n",k); - ret = -1; - goto bad_val; - } - - argc -=1; - argv +=1; - if (argc <= 0) { - fprintf(stderr, "Error: no index specified action: %s\n",k); - ret = -1; - goto bad_val; - } - - if (matches(*argv, "index") == 0) { - NEXT_ARG(); - if (get_u32(&i, *argv, 10)) { - fprintf(stderr, "Illegal \"index\"\n"); - ret = -1; - goto bad_val; - } - argc -=1; - argv +=1; - } else { - fprintf(stderr, "Error: no index specified action: %s\n",k); - ret = -1; - goto bad_val; - } - - tail2 = NLMSG_TAIL(&req.n); - addattr_l(&req.n, MAX_MSG, ++prio, NULL, 0); - addattr_l(&req.n, MAX_MSG, TCA_ACT_KIND, k, strlen(k) + 1); - addattr32(&req.n, MAX_MSG, TCA_ACT_INDEX, i); - tail2->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail2; - - } - - tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail; - - req.n.nlmsg_seq = rth.dump = ++rth.seq; - if (cmd == RTM_GETACTION) - ans = &req.n; - - if (rtnl_talk(&rth, &req.n, 0, 0, ans, NULL, NULL) < 0) { - fprintf(stderr, "We have an error talking to the kernel\n"); - return 1; - } - - if (ans && do_print_action(NULL, &req.n, (void*)stdout) < 0) { - fprintf(stderr, "Dump terminated\n"); - return 1; - } - - *argc_p = argc; - *argv_p = argv; -bad_val: - return ret; -} - -int tc_action_modify(int cmd, unsigned flags, int *argc_p, char ***argv_p) -{ - int argc = *argc_p; - char **argv = *argv_p; - int ret = 0; - - struct rtattr *tail; - struct { - struct nlmsghdr n; - struct tcamsg t; - char buf[MAX_MSG]; - } req; - - req.t.tca_family = AF_UNSPEC; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|flags; - req.n.nlmsg_type = cmd; - tail = NLMSG_TAIL(&req.n); - argc -=1; - argv +=1; - if (parse_action(&argc, &argv, TCA_ACT_TAB, &req.n)) { - fprintf(stderr, "Illegal \"action\"\n"); - return -1; - } - tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail; - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) { - fprintf(stderr, "We have an error talking to the kernel\n"); - ret = -1; - } - - *argc_p = argc; - *argv_p = argv; - - return ret; -} - -int tc_act_list_or_flush(int argc, char **argv, int event) -{ - int ret = 0, prio = 0, msg_size = 0; - char k[16]; - struct rtattr *tail,*tail2; - struct action_util *a = NULL; - struct { - struct nlmsghdr n; - struct tcamsg t; - char buf[MAX_MSG]; - } req; - - req.t.tca_family = AF_UNSPEC; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcamsg)); - - tail = NLMSG_TAIL(&req.n); - addattr_l(&req.n, MAX_MSG, TCA_ACT_TAB, NULL, 0); - tail2 = NLMSG_TAIL(&req.n); - - strncpy(k, *argv, sizeof (k) - 1); -#ifdef CONFIG_GACT - if (!gact_ld) { - get_action_kind("gact"); - } -#endif - a = get_action_kind(k); - if (NULL == a) { - fprintf(stderr,"bad action %s\n",k); - goto bad_val; - } - if (strcmp(a->id, k) != 0) { - fprintf(stderr,"bad action %s\n",k); - goto bad_val; - } - strncpy(k, *argv, sizeof (k) - 1); - - addattr_l(&req.n, MAX_MSG, ++prio, NULL, 0); - addattr_l(&req.n, MAX_MSG, TCA_ACT_KIND, k, strlen(k) + 1); - tail2->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail2; - tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail; - - msg_size = NLMSG_ALIGN(req.n.nlmsg_len) - NLMSG_ALIGN(sizeof(struct nlmsghdr)); - - if (event == RTM_GETACTION) { - if (rtnl_dump_request(&rth, event, (void *)&req.t, msg_size) < 0) { - perror("Cannot send dump request"); - return 1; - } - ret = rtnl_dump_filter(&rth, do_print_action, stdout, NULL, NULL); - } - - if (event == RTM_DELACTION) { - req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len); - req.n.nlmsg_type = RTM_DELACTION; - req.n.nlmsg_flags |= NLM_F_ROOT; - req.n.nlmsg_flags |= NLM_F_REQUEST; - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) { - fprintf(stderr, "We have an error flushing\n"); - return 1; - } - - } - -bad_val: - - return ret; -} - -int do_action(int argc, char **argv) -{ - - int ret = 0; - - while (argc > 0) { - - if (matches(*argv, "add") == 0) { - ret = tc_action_modify(RTM_NEWACTION, NLM_F_EXCL|NLM_F_CREATE, &argc, &argv); - } else if (matches(*argv, "change") == 0 || - matches(*argv, "replace") == 0) { - ret = tc_action_modify(RTM_NEWACTION, NLM_F_CREATE|NLM_F_REPLACE, &argc, &argv); - } else if (matches(*argv, "delete") == 0) { - argc -=1; - argv +=1; - ret = tc_action_gd(RTM_DELACTION, 0, &argc, &argv); - } else if (matches(*argv, "get") == 0) { - argc -=1; - argv +=1; - ret = tc_action_gd(RTM_GETACTION, 0, &argc, &argv); - } else if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 - || matches(*argv, "lst") == 0) { - if (argc <= 2) { - act_usage(); - return -1; - } - return tc_act_list_or_flush(argc-2, argv+2, RTM_GETACTION); - } else if (matches(*argv, "flush") == 0) { - if (argc <= 2) { - act_usage(); - return -1; - } - return tc_act_list_or_flush(argc-2, argv+2, RTM_DELACTION); - } else if (matches(*argv, "help") == 0) { - act_usage(); - return -1; - } else { - - ret = -1; - } - - if (ret < 0) { - fprintf(stderr, "Command \"%s\" is unknown, try \"tc action help\".\n", *argv); - return -1; - } - } - - return 0; -} - diff --git a/tc/m_ematch.c b/tc/m_ematch.c deleted file mode 100644 index 44c621b..0000000 --- a/tc/m_ematch.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * m_ematch.c Extended Matches - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Thomas Graf <tgraf@suug.ch> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <dlfcn.h> -#include <stdarg.h> -#include <errno.h> - -#include "utils.h" -#include "tc_util.h" -#include "m_ematch.h" - -#define EMATCH_MAP "/etc/iproute2/ematch_map" - -static struct ematch_util *ematch_list; - -/* export to bison parser */ -int ematch_argc; -char **ematch_argv; -char *ematch_err = NULL; -struct ematch *ematch_root; - -static int begin_argc; -static char **begin_argv; - -static inline void map_warning(int num, char *kind) -{ - fprintf(stderr, - "Error: Unable to find ematch \"%s\" in %s\n" \ - "Please assign a unique ID to the ematch kind the suggested " \ - "entry is:\n" \ - "\t%d\t%s\n", - kind, EMATCH_MAP, num, kind); -} - -static int lookup_map(__u16 num, char *dst, int len, const char *file) -{ - int err = -EINVAL; - char buf[512]; - FILE *fd = fopen(file, "r"); - - if (fd == NULL) - return -errno; - - while (fgets(buf, sizeof(buf), fd)) { - char namebuf[512], *p = buf; - int id; - - while (*p == ' ' || *p == '\t') - p++; - if (*p == '#' || *p == '\n' || *p == 0) - continue; - - if (sscanf(p, "%d %s", &id, namebuf) != 2) { - fprintf(stderr, "ematch map %s corrupted at %s\n", - file, p); - goto out; - } - - if (id == num) { - if (dst) - strncpy(dst, namebuf, len - 1); - err = 0; - goto out; - } - } - - err = -ENOENT; -out: - fclose(fd); - return err; -} - -static int lookup_map_id(char *kind, int *dst, const char *file) -{ - int err = -EINVAL; - char buf[512]; - FILE *fd = fopen(file, "r"); - - if (fd == NULL) - return -errno; - - while (fgets(buf, sizeof(buf), fd)) { - char namebuf[512], *p = buf; - int id; - - while (*p == ' ' || *p == '\t') - p++; - if (*p == '#' || *p == '\n' || *p == 0) - continue; - - if (sscanf(p, "%d %s", &id, namebuf) != 2) { - fprintf(stderr, "ematch map %s corrupted at %s\n", - file, p); - goto out; - } - - if (!strcasecmp(namebuf, kind)) { - if (dst) - *dst = id; - err = 0; - goto out; - } - } - - err = -ENOENT; - *dst = 0; -out: - fclose(fd); - return err; -} - -static struct ematch_util *get_ematch_kind(char *kind) -{ - static void *body; - void *dlh; - char buf[256]; - struct ematch_util *e; - - for (e = ematch_list; e; e = e->next) { - if (strcmp(e->kind, kind) == 0) - return e; - } - - snprintf(buf, sizeof(buf), "em_%s.so", kind); - dlh = dlopen(buf, RTLD_LAZY); - if (dlh == NULL) { - dlh = body; - if (dlh == NULL) { - dlh = body = dlopen(NULL, RTLD_LAZY); - if (dlh == NULL) - return NULL; - } - } - - snprintf(buf, sizeof(buf), "%s_ematch_util", kind); - e = dlsym(dlh, buf); - if (e == NULL) - return NULL; - - e->next = ematch_list; - ematch_list = e; - - return e; -} - -static struct ematch_util *get_ematch_kind_num(__u16 kind) -{ - char name[32]; - - if (lookup_map(kind, name, sizeof(name), EMATCH_MAP) < 0) - return NULL; - - return get_ematch_kind(name); - - return NULL; -} - -static int parse_tree(struct nlmsghdr *n, struct ematch *tree) -{ - int index = 1; - struct ematch *t; - - for (t = tree; t; t = t->next) { - struct rtattr *tail = NLMSG_TAIL(n); - struct tcf_ematch_hdr hdr = { - .flags = t->relation - }; - - if (t->inverted) - hdr.flags |= TCF_EM_INVERT; - - addattr_l(n, MAX_MSG, index++, NULL, 0); - - if (t->child) { - __u32 r = t->child_ref; - addraw_l(n, MAX_MSG, &hdr, sizeof(hdr)); - addraw_l(n, MAX_MSG, &r, sizeof(r)); - } else { - int num = 0, err; - char buf[64]; - struct ematch_util *e; - - if (t->args == NULL) - return -1; - - strncpy(buf, (char*) t->args->data, sizeof(buf)-1); - e = get_ematch_kind(buf); - if (e == NULL) { - fprintf(stderr, "Unknown ematch \"%s\"\n", - buf); - return -1; - } - - err = lookup_map_id(buf, &num, EMATCH_MAP); - if (err < 0) { - if (err == -ENOENT) - map_warning(e->kind_num, buf); - return err; - } - - hdr.kind = num; - if (e->parse_eopt(n, &hdr, t->args->next) < 0) - return -1; - } - - tail->rta_len = (void*) NLMSG_TAIL(n) - (void*) tail; - } - - return 0; -} - -static int flatten_tree(struct ematch *head, struct ematch *tree) -{ - int i, count = 0; - struct ematch *t; - - for (;;) { - count++; - - if (tree->child) { - for (t = head; t->next; t = t->next); - t->next = tree->child; - count += flatten_tree(head, tree->child); - } - - if (tree->relation == 0) - break; - - tree = tree->next; - } - - for (i = 0, t = head; t; t = t->next, i++) - t->index = i; - - for (t = head; t; t = t->next) - if (t->child) - t->child_ref = t->child->index; - - return count; -} - -int em_parse_error(int err, struct bstr *args, struct bstr *carg, - struct ematch_util *e, char *fmt, ...) -{ - va_list a; - - va_start(a, fmt); - vfprintf(stderr, fmt, a); - va_end(a); - - if (ematch_err) - fprintf(stderr, ": %s\n... ", ematch_err); - else - fprintf(stderr, "\n... "); - - while (ematch_argc < begin_argc) { - if (ematch_argc == (begin_argc - 1)) - fprintf(stderr, ">>%s<< ", *begin_argv); - else - fprintf(stderr, "%s ", *begin_argv); - begin_argv++; - begin_argc--; - } - - fprintf(stderr, "...\n"); - - if (args) { - fprintf(stderr, "... %s(", e->kind); - while (args) { - fprintf(stderr, "%s", args == carg ? ">>" : ""); - bstr_print(stderr, args, 1); - fprintf(stderr, "%s%s", args == carg ? "<<" : "", - args->next ? " " : ""); - args = args->next; - } - fprintf(stderr, ")...\n"); - - } - - if (e == NULL) { - fprintf(stderr, - "Usage: EXPR\n" \ - "where: EXPR := TERM [ { and | or } EXPR ]\n" \ - " TERM := [ not ] { MATCH | '(' EXPR ')' }\n" \ - " MATCH := module '(' ARGS ')'\n" \ - " ARGS := ARG1 ARG2 ...\n" \ - "\n" \ - "Example: a(x y) and not (b(x) or c(x y z))\n"); - } else - e->print_usage(stderr); - - return -err; -} - -static inline void free_ematch_err(void) -{ - if (ematch_err) { - free(ematch_err); - ematch_err = NULL; - } -} - -extern int ematch_parse(void); - -int parse_ematch(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) -{ - begin_argc = ematch_argc = *argc_p; - begin_argv = ematch_argv = *argv_p; - - if (ematch_parse()) { - int err = em_parse_error(EINVAL, NULL, NULL, NULL, - "Parse error"); - free_ematch_err(); - return err; - } - - free_ematch_err(); - - /* undo look ahead by parser */ - ematch_argc++; - ematch_argv--; - - if (ematch_root) { - struct rtattr *tail, *tail_list; - - struct tcf_ematch_tree_hdr hdr = { - .nmatches = flatten_tree(ematch_root, ematch_root), - .progid = TCF_EM_PROG_TC - }; - - tail = NLMSG_TAIL(n); - addattr_l(n, MAX_MSG, tca_id, NULL, 0); - addattr_l(n, MAX_MSG, TCA_EMATCH_TREE_HDR, &hdr, sizeof(hdr)); - - tail_list = NLMSG_TAIL(n); - addattr_l(n, MAX_MSG, TCA_EMATCH_TREE_LIST, NULL, 0); - - if (parse_tree(n, ematch_root) < 0) - return -1; - - tail_list->rta_len = (void*) NLMSG_TAIL(n) - (void*) tail_list; - tail->rta_len = (void*) NLMSG_TAIL(n) - (void*) tail; - } - - *argc_p = ematch_argc; - *argv_p = ematch_argv; - - return 0; -} - -static int print_ematch_seq(FILE *fd, struct rtattr **tb, int start, - int prefix) -{ - int n, i = start; - struct tcf_ematch_hdr *hdr; - int dlen; - void *data; - - for (;;) { - if (tb[i] == NULL) - return -1; - - dlen = RTA_PAYLOAD(tb[i]) - sizeof(*hdr); - data = (void *) RTA_DATA(tb[i]) + sizeof(*hdr); - - if (dlen < 0) - return -1; - - hdr = RTA_DATA(tb[i]); - - if (hdr->flags & TCF_EM_INVERT) - fprintf(fd, "NOT "); - - if (hdr->kind == 0) { - __u32 ref; - - if (dlen < sizeof(__u32)) - return -1; - - ref = *(__u32 *) data; - fprintf(fd, "(\n"); - for (n = 0; n <= prefix; n++) - fprintf(fd, " "); - if (print_ematch_seq(fd, tb, ref + 1, prefix + 1) < 0) - return -1; - for (n = 0; n < prefix; n++) - fprintf(fd, " "); - fprintf(fd, ") "); - - } else { - struct ematch_util *e; - - e = get_ematch_kind_num(hdr->kind); - if (e == NULL) - fprintf(fd, "[unknown ematch %d]\n", - hdr->kind); - else { - fprintf(fd, "%s(", e->kind); - if (e->print_eopt(fd, hdr, data, dlen) < 0) - return -1; - fprintf(fd, ")\n"); - } - if (hdr->flags & TCF_EM_REL_MASK) - for (n = 0; n < prefix; n++) - fprintf(fd, " "); - } - - switch (hdr->flags & TCF_EM_REL_MASK) { - case TCF_EM_REL_AND: - fprintf(fd, "AND "); - break; - - case TCF_EM_REL_OR: - fprintf(fd, "OR "); - break; - - default: - return 0; - } - - i++; - } - - return 0; -} - -static int print_ematch_list(FILE *fd, struct tcf_ematch_tree_hdr *hdr, - struct rtattr *rta) -{ - int err = -1; - struct rtattr **tb; - - tb = malloc((hdr->nmatches + 1) * sizeof(struct rtattr *)); - if (tb == NULL) - return -1; - - if (parse_rtattr_nested(tb, hdr->nmatches, rta) < 0) - goto errout; - - fprintf(fd, "\n "); - if (print_ematch_seq(fd, tb, 1, 1) < 0) - goto errout; - - err = 0; -errout: - free(tb); - return err; -} - -int print_ematch(FILE *fd, const struct rtattr *rta) -{ - struct rtattr *tb[TCA_EMATCH_TREE_MAX+1]; - struct tcf_ematch_tree_hdr *hdr; - - if (parse_rtattr_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0) - return -1; - - if (tb[TCA_EMATCH_TREE_HDR] == NULL) { - fprintf(stderr, "Missing ematch tree header\n"); - return -1; - } - - if (tb[TCA_EMATCH_TREE_LIST] == NULL) { - fprintf(stderr, "Missing ematch tree list\n"); - return -1; - } - - if (RTA_PAYLOAD(tb[TCA_EMATCH_TREE_HDR]) < sizeof(*hdr)) { - fprintf(stderr, "Ematch tree header size mismatch\n"); - return -1; - } - - hdr = RTA_DATA(tb[TCA_EMATCH_TREE_HDR]); - - return print_ematch_list(fd, hdr, tb[TCA_EMATCH_TREE_LIST]); -} diff --git a/tc/m_ematch.h b/tc/m_ematch.h deleted file mode 100644 index ed98446..0000000 --- a/tc/m_ematch.h +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef __TC_EMATCH_H_ -#define __TC_EMATCH_H_ - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - -#define EMATCHKINDSIZ 16 - -struct bstr -{ - char *data; - unsigned int len; - int quoted; - struct bstr *next; -}; - -static inline struct bstr * bstr_alloc(const char *text) -{ - struct bstr *b = calloc(1, sizeof(*b)); - - if (b == NULL) - return NULL; - - b->data = strdup(text); - if (b->data == NULL) { - free(b); - return NULL; - } - - b->len = strlen(text); - - return b; -} - -static inline struct bstr * bstr_new(char *data, unsigned int len) -{ - struct bstr *b = calloc(1, sizeof(*b)); - - if (b == NULL) - return NULL; - - b->data = data; - b->len = len; - - return b; -} - -static inline int bstrcmp(struct bstr *b, const char *text) -{ - int len = strlen(text); - int d = b->len - len; - - if (d == 0) - return strncmp(b->data, text, len); - - return d; -} - -static inline unsigned long bstrtoul(struct bstr *b) -{ - char *inv = NULL; - unsigned long l; - char buf[b->len+1]; - - memcpy(buf, b->data, b->len); - buf[b->len] = '\0'; - - l = strtol(buf, &inv, 0); - if (l == ULONG_MAX || inv == buf) - return LONG_MAX; - - return l; -} - -static inline void bstr_print(FILE *fd, struct bstr *b, int ascii) -{ - int i; - char *s = b->data; - - if (ascii) - for (i = 0; i < b->len; i++) - fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.'); - else { - for (i = 0; i < b->len; i++) - fprintf(fd, "%02x", s[i]); - fprintf(fd, "\""); - for (i = 0; i < b->len; i++) - fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.'); - fprintf(fd, "\""); - } -} - -static inline struct bstr *bstr_next(struct bstr *b) -{ - return b->next; -} - -struct ematch -{ - struct bstr *args; - int index; - int inverted; - int relation; - int child_ref; - struct ematch *child; - struct ematch *next; -}; - -static inline struct ematch * new_ematch(struct bstr *args, int inverted) -{ - struct ematch *e = calloc(1, sizeof(*e)); - - if (e == NULL) - return NULL; - - e->args = args; - e->inverted = inverted; - - return e; -} - -static inline void print_ematch_tree(struct ematch *tree) -{ - struct ematch *t; - - for (t = tree; t; t = t->next) { - if (t->inverted) - printf("NOT "); - - if (t->child) { - printf("("); - print_ematch_tree(t->child); - printf(")"); - } else { - struct bstr *b; - for (b = t->args; b; b = b->next) - printf("%s%s", b->data, b->next ? " " : ""); - } - - if (t->relation == TCF_EM_REL_AND) - printf(" AND "); - else if (t->relation == TCF_EM_REL_OR) - printf(" OR "); - } -} - -struct ematch_util -{ - char kind[EMATCHKINDSIZ]; - int kind_num; - int (*parse_eopt)(struct nlmsghdr *,struct tcf_ematch_hdr *, - struct bstr *); - int (*print_eopt)(FILE *, struct tcf_ematch_hdr *, void *, int); - void (*print_usage)(FILE *); - struct ematch_util *next; -}; - -static inline int parse_layer(struct bstr *b) -{ - if (*((char *) b->data) == 'l') - return TCF_LAYER_LINK; - else if (*((char *) b->data) == 'n') - return TCF_LAYER_NETWORK; - else if (*((char *) b->data) == 't') - return TCF_LAYER_TRANSPORT; - else - return INT_MAX; -} - -extern int em_parse_error(int err, struct bstr *args, struct bstr *carg, - struct ematch_util *, char *fmt, ...); -extern int print_ematch(FILE *, const struct rtattr *); -extern int parse_ematch(int *, char ***, int, struct nlmsghdr *); - -#endif diff --git a/tc/m_estimator.c b/tc/m_estimator.c deleted file mode 100644 index 78eda7a..0000000 --- a/tc/m_estimator.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * m_estimator.c Parse/print estimator module options. - * - * This program is free software; you can u32istribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - -static void est_help(void); - -static void est_help(void) -{ - fprintf(stderr, "Usage: ... estimator INTERVAL TIME-CONST\n"); - fprintf(stderr, " INTERVAL is interval between measurements\n"); - fprintf(stderr, " TIME-CONST is averaging time constant\n"); - fprintf(stderr, "Example: ... est 1sec 8sec\n"); - return; -} - -int parse_estimator(int *p_argc, char ***p_argv, struct tc_estimator *est) -{ - int argc = *p_argc; - char **argv = *p_argv; - unsigned A, time_const; - - NEXT_ARG(); - if (est->ewma_log) - duparg("estimator", *argv); - if (matches(*argv, "help") == 0) - est_help(); - if (get_usecs(&A, *argv)) - invarg("estimator", "invalid estimator interval"); - NEXT_ARG(); - if (matches(*argv, "help") == 0) - est_help(); - if (get_usecs(&time_const, *argv)) - invarg("estimator", "invalid estimator time constant"); - if (tc_setup_estimator(A, time_const, est) < 0) { - fprintf(stderr, "Error: estimator parameters are out of range.\n"); - return -1; - } - if (show_raw) - fprintf(stderr, "[estimator i=%u e=%u]\n", est->interval, est->ewma_log); - *p_argc = argc; - *p_argv = argv; - return 0; -} diff --git a/tc/m_gact.c b/tc/m_gact.c deleted file mode 100644 index 4bb5041..0000000 --- a/tc/m_gact.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * m_gact.c generic actions module - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim (hadi@cyberus.ca) - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" -#include <linux/tc_act/tc_gact.h> - -/* define to turn on probablity stuff */ - -#ifdef CONFIG_GACT_PROB -static const char *prob_n2a(int p) -{ - if (p == PGACT_NONE) - return "none"; - if (p == PGACT_NETRAND) - return "netrand"; - if (p == PGACT_DETERM) - return "determ"; - return "none"; -} -#endif - -static void -explain(void) -{ -#ifdef CONFIG_GACT_PROB - fprintf(stderr, "Usage: ... gact <ACTION> [RAND] [INDEX]\n"); - fprintf(stderr, - "Where: ACTION := reclassify | drop | continue | pass " - "RAND := random <RANDTYPE> <ACTION> <VAL>" - "RANDTYPE := netrand | determ" - "VAL : = value not exceeding 10000" - "INDEX := index value used" - "\n"); -#else - fprintf(stderr, "Usage: ... gact <ACTION> [INDEX]\n"); - fprintf(stderr, - "Where: ACTION := reclassify | drop | continue | pass " - "INDEX := index value used" - "\n"); -#endif -} - -#define usage() return(-1) - -int -get_act(char ***argv_p) -{ - char **argv = *argv_p; - - if (matches(*argv, "reclassify") == 0) { - return TC_ACT_RECLASSIFY; - } else if (matches(*argv, "drop") == 0 || matches(*argv, "shot") == 0) { - return TC_ACT_SHOT; - } else if (matches(*argv, "continue") == 0) { - return TC_ACT_UNSPEC; - } else if (matches(*argv, "pipe") == 0) { - return TC_ACT_PIPE; - } else if (matches(*argv, "pass") == 0 || matches(*argv, "ok") == 0) { - return TC_ACT_OK; - } else { - fprintf(stderr,"bad action type %s\n",*argv); - return -10; - } -} - -int -parse_gact(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) -{ - int argc = *argc_p; - char **argv = *argv_p; - int ok = 0; - int action = TC_POLICE_RECLASSIFY; - struct tc_gact p; -#ifdef CONFIG_GACT_PROB - int rd = 0; - struct tc_gact_p pp; -#endif - struct rtattr *tail; - - memset(&p, 0, sizeof (p)); - p.action = TC_POLICE_RECLASSIFY; - - if (argc < 0) - return -1; - - - if (matches(*argv, "gact") == 0) { - ok++; - } else { - action = get_act(&argv); - if (action != -10) { - p.action = action; - ok++; - } else { - explain(); - return action; - } - } - - if (ok) { - argc--; - argv++; - } - -#ifdef CONFIG_GACT_PROB - if (ok && argc > 0) { - if (matches(*argv, "random") == 0) { - rd = 1; - NEXT_ARG(); - if (matches(*argv, "netrand") == 0) { - NEXT_ARG(); - pp.ptype = PGACT_NETRAND; - } else if (matches(*argv, "determ") == 0) { - NEXT_ARG(); - pp.ptype = PGACT_DETERM; - } else { - fprintf(stderr, "Illegal \"random type\"\n"); - return -1; - } - - action = get_act(&argv); - if (action != -10) { /* FIXME */ - pp.paction = action; - } else { - explain(); - return -1; - } - argc--; - argv++; - if (get_u16(&pp.pval, *argv, 10)) { - fprintf(stderr, "Illegal probability val 0x%x\n",pp.pval); - return -1; - } - if (pp.pval > 10000) { - fprintf(stderr, "Illegal probability val 0x%x\n",pp.pval); - return -1; - } - argc--; - argv++; - } - } -#endif - - if (argc > 0) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); - if (get_u32(&p.index, *argv, 10)) { - fprintf(stderr, "Illegal \"index\"\n"); - return -1; - } - argc--; - argv++; - ok++; - } - } - - if (!ok) - return -1; - - tail = NLMSG_TAIL(n); - addattr_l(n, MAX_MSG, tca_id, NULL, 0); - addattr_l(n, MAX_MSG, TCA_GACT_PARMS, &p, sizeof (p)); -#ifdef CONFIG_GACT_PROB - if (rd) { - addattr_l(n, MAX_MSG, TCA_GACT_PROB, &pp, sizeof (pp)); - } -#endif - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - - *argc_p = argc; - *argv_p = argv; - return 0; -} - -int -print_gact(struct action_util *au,FILE * f, struct rtattr *arg) -{ - SPRINT_BUF(b1); -#ifdef CONFIG_GACT_PROB - SPRINT_BUF(b2); - struct tc_gact_p *pp = NULL; - struct tc_gact_p pp_dummy; -#endif - struct tc_gact *p = NULL; - struct rtattr *tb[TCA_GACT_MAX + 1]; - - if (arg == NULL) - return -1; - - parse_rtattr_nested(tb, TCA_GACT_MAX, arg); - - if (tb[TCA_GACT_PARMS] == NULL) { - fprintf(f, "[NULL gact parameters]"); - return -1; - } - p = RTA_DATA(tb[TCA_GACT_PARMS]); - - fprintf(f, "gact action %s", action_n2a(p->action, b1, sizeof (b1))); -#ifdef CONFIG_GACT_PROB - if (NULL != tb[TCA_GACT_PROB]) { - pp = RTA_DATA(tb[TCA_GACT_PROB]); - } else { - /* need to keep consistent output */ - memset(&pp_dummy, 0, sizeof (pp_dummy)); - pp = &pp_dummy; - } - fprintf(f, "\n\t random type %s %s val %d",prob_n2a(pp->ptype), action_n2a(pp->paction, b2, sizeof (b2)), pp->pval); -#endif - fprintf(f, "\n\t index %d ref %d bind %d",p->index, p->refcnt, p->bindcnt); - if (show_stats) { - if (tb[TCA_GACT_TM]) { - struct tcf_t *tm = RTA_DATA(tb[TCA_GACT_TM]); - print_tm(f,tm); - } - } - fprintf(f, "\n "); - return 0; -} - -struct action_util gact_action_util = { - .id = "gact", - .parse_aopt = parse_gact, - .print_aopt = print_gact, -}; diff --git a/tc/m_ipt.c b/tc/m_ipt.c deleted file mode 100644 index 5acc6fa..0000000 --- a/tc/m_ipt.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * m_ipt.c iptables based targets - * utilities mostly ripped from iptables <duh, its the linux way> - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim (hadi@cyberus.ca) - * - * TODO: bad bad hardcoding IPT_LIB_DIR and PROC_SYS_MODPROBE - * -*/ - -#include <syslog.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <linux/types.h> -#include <iptables.h> -#include <linux/netfilter_ipv4/ip_tables.h> -#include "utils.h" -#include "tc_util.h" -#include <linux/tc_act/tc_ipt.h> -#include <stdio.h> -#include <dlfcn.h> -#include <getopt.h> -#include <errno.h> -#include <string.h> -#include <netdb.h> -#include <stdlib.h> -#include <ctype.h> -#include <stdarg.h> -#include <limits.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/wait.h> - -const char *pname = "tc-ipt"; -const char *tname = "mangle"; -const char *pversion = "0.1"; - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef IPT_LIB_DIR -#define IPT_LIB_DIR "/usr/local/lib/iptables" -#endif - -#ifndef PROC_SYS_MODPROBE -#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" -#endif - -static const char *ipthooks[] = { - "NF_IP_PRE_ROUTING", - "NF_IP_LOCAL_IN", - "NF_IP_FORWARD", - "NF_IP_LOCAL_OUT", - "NF_IP_POST_ROUTING", -}; - -static struct option original_opts[] = { - {"jump", 1, 0, 'j'}, - {0, 0, 0, 0} -}; - -static struct iptables_target *t_list = NULL; -static struct option *opts = original_opts; -static unsigned int global_option_offset = 0; -#define OPTION_OFFSET 256 - - -void -register_target(struct iptables_target *me) -{ -/* fprintf(stderr, "\nDummy register_target %s \n", me->name); -*/ - me->next = t_list; - t_list = me; - -} - -void -exit_tryhelp(int status) -{ - fprintf(stderr, "Try `%s -h' or '%s --help' for more information.\n", - pname, pname); - exit(status); -} - -void -exit_error(enum exittype status, char *msg, ...) -{ - va_list args; - - va_start(args, msg); - fprintf(stderr, "%s v%s: ", pname, pversion); - vfprintf(stderr, msg, args); - va_end(args); - fprintf(stderr, "\n"); - if (status == PARAMETER_PROBLEM) - exit_tryhelp(status); - if (status == VERSION_PROBLEM) - fprintf(stderr, - "Perhaps iptables or your kernel needs to be upgraded.\n"); - exit(status); -} - -/* stolen from iptables 1.2.11 -They should really have them as a library so i can link to them -Email them next time i remember -*/ - -char * -addr_to_dotted(const struct in_addr *addrp) -{ - static char buf[20]; - const unsigned char *bytep; - - bytep = (const unsigned char *) &(addrp->s_addr); - sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]); - return buf; -} - -int string_to_number_ll(const char *s, unsigned long long min, - unsigned long long max, - unsigned long long *ret) -{ - unsigned long long number; - char *end; - - /* Handle hex, octal, etc. */ - errno = 0; - number = strtoull(s, &end, 0); - if (*end == '\0' && end != s) { - /* we parsed a number, let's see if we want this */ - if (errno != ERANGE && min <= number && (!max || number <= max)) { - *ret = number; - return 0; - } - } - return -1; -} - -int string_to_number_l(const char *s, unsigned long min, unsigned long max, - unsigned long *ret) -{ - int result; - unsigned long long number; - - result = string_to_number_ll(s, min, max, &number); - *ret = (unsigned long)number; - - return result; -} - -int string_to_number(const char *s, unsigned int min, unsigned int max, - unsigned int *ret) -{ - int result; - unsigned long number; - - result = string_to_number_l(s, min, max, &number); - *ret = (unsigned int)number; - - return result; -} - -static void free_opts(struct option *opts) -{ - if (opts != original_opts) { - free(opts); - opts = original_opts; - global_option_offset = 0; - } -} - -static struct option * -merge_options(struct option *oldopts, const struct option *newopts, - unsigned int *option_offset) -{ - struct option *merge; - unsigned int num_old, num_new, i; - - for (num_old = 0; oldopts[num_old].name; num_old++) ; - for (num_new = 0; newopts[num_new].name; num_new++) ; - - *option_offset = global_option_offset + OPTION_OFFSET; - - merge = malloc(sizeof (struct option) * (num_new + num_old + 1)); - memcpy(merge, oldopts, num_old * sizeof (struct option)); - for (i = 0; i < num_new; i++) { - merge[num_old + i] = newopts[i]; - merge[num_old + i].val += *option_offset; - } - memset(merge + num_old + num_new, 0, sizeof (struct option)); - - return merge; -} - -static void * -fw_calloc(size_t count, size_t size) -{ - void *p; - - if ((p = (void *) calloc(count, size)) == NULL) { - perror("iptables: calloc failed"); - exit(1); - } - return p; -} - -static struct iptables_target * -find_t(char *name) -{ - struct iptables_target *m; - for (m = t_list; m; m = m->next) { - if (strcmp(m->name, name) == 0) - return m; - } - - return NULL; -} - -static struct iptables_target * -get_target_name(char *name) -{ - void *handle; - char *error; - char *new_name, *lname; - struct iptables_target *m; - - char path[sizeof (IPT_LIB_DIR) + sizeof ("/libipt_.so") + strlen(name)]; - - new_name = malloc(strlen(name) + 1); - lname = malloc(strlen(name) + 1); - if (new_name) - memset(new_name, '\0', strlen(name) + 1); - else - exit_error(PARAMETER_PROBLEM, "get_target_name"); - - if (lname) - memset(lname, '\0', strlen(name) + 1); - else - exit_error(PARAMETER_PROBLEM, "get_target_name"); - - strcpy(new_name, name); - strcpy(lname, name); - - if (isupper(lname[0])) { - int i; - for (i = 0; i < strlen(name); i++) { - lname[i] = tolower(lname[i]); - } - } - - if (islower(new_name[0])) { - int i; - for (i = 0; i < strlen(new_name); i++) { - new_name[i] = toupper(new_name[i]); - } - } - - sprintf(path, IPT_LIB_DIR "/libipt_%s.so", new_name); - handle = dlopen(path, RTLD_LAZY); - if (!handle) { - sprintf(path, IPT_LIB_DIR "/libipt_%s.so", lname); - handle = dlopen(path, RTLD_LAZY); - if (!handle) { - fputs(dlerror(), stderr); - printf("\n"); - return NULL; - } - } - - m = dlsym(handle, new_name); - if ((error = dlerror()) != NULL) { - m = (struct iptables_target *) dlsym(handle, lname); - if ((error = dlerror()) != NULL) { - m = find_t(new_name); - if (NULL == m) { - m = find_t(lname); - if (NULL == m) { - fputs(error, stderr); - fprintf(stderr, "\n"); - dlclose(handle); - return NULL; - } - } - } - } - - return m; -} - - -struct in_addr *dotted_to_addr(const char *dotted) -{ - static struct in_addr addr; - unsigned char *addrp; - char *p, *q; - unsigned int onebyte; - int i; - char buf[20]; - - /* copy dotted string, because we need to modify it */ - strncpy(buf, dotted, sizeof (buf) - 1); - addrp = (unsigned char *) &(addr.s_addr); - - p = buf; - for (i = 0; i < 3; i++) { - if ((q = strchr(p, '.')) == NULL) - return (struct in_addr *) NULL; - - *q = '\0'; - if (string_to_number(p, 0, 255, &onebyte) == -1) - return (struct in_addr *) NULL; - - addrp[i] = (unsigned char) onebyte; - p = q + 1; - } - - /* we've checked 3 bytes, now we check the last one */ - if (string_to_number(p, 0, 255, &onebyte) == -1) - return (struct in_addr *) NULL; - - addrp[3] = (unsigned char) onebyte; - - return &addr; -} - -static void set_revision(char *name, u_int8_t revision) -{ - /* Old kernel sources don't have ".revision" field, - * but we stole a byte from name. */ - name[IPT_FUNCTION_MAXNAMELEN - 2] = '\0'; - name[IPT_FUNCTION_MAXNAMELEN - 1] = revision; -} - -/* - * we may need to check for version mismatch -*/ -int -build_st(struct iptables_target *target, struct ipt_entry_target *t) -{ - unsigned int nfcache = 0; - - if (target) { - size_t size; - - size = - IPT_ALIGN(sizeof (struct ipt_entry_target)) + target->size; - - if (NULL == t) { - target->t = fw_calloc(1, size); - target->t->u.target_size = size; - - if (target->init != NULL) - target->init(target->t, &nfcache); - set_revision(target->t->u.user.name, target->revision); - } else { - target->t = t; - } - strcpy(target->t->u.user.name, target->name); - return 0; - } - - return -1; -} - -static int parse_ipt(struct action_util *a,int *argc_p, - char ***argv_p, int tca_id, struct nlmsghdr *n) -{ - struct iptables_target *m = NULL; - struct ipt_entry fw; - struct rtattr *tail; - int c; - int rargc = *argc_p; - char **argv = *argv_p; - int argc = 0, iargc = 0; - char k[16]; - int res = -1; - int size = 0; - int iok = 0, ok = 0; - __u32 hook = 0, index = 0; - res = 0; - - { - int i; - for (i = 0; i < rargc; i++) { - if (NULL == argv[i] || 0 == strcmp(argv[i], "action")) { - break; - } - } - iargc = argc = i; - } - - if (argc <= 2) { - fprintf(stderr,"bad arguements to ipt %d vs %d \n", argc, rargc); - return -1; - } - - while (1) { - c = getopt_long(argc, argv, "j:", opts, NULL); - if (c == -1) - break; - switch (c) { - case 'j': - m = get_target_name(optarg); - if (NULL != m) { - - if (0 > build_st(m, NULL)) { - printf(" %s error \n", m->name); - return -1; - } - opts = - merge_options(opts, m->extra_opts, - &m->option_offset); - } else { - fprintf(stderr," failed to find target %s\n\n", optarg); - return -1; - } - ok++; - break; - - default: - memset(&fw, 0, sizeof (fw)); - if (m) { - m->parse(c - m->option_offset, argv, 0, - &m->tflags, NULL, &m->t); - } else { - fprintf(stderr," failed to find target %s\n\n", optarg); - return -1; - - } - ok++; - break; - - } - } - - if (iargc > optind) { - if (matches(argv[optind], "index") == 0) { - if (get_u32(&index, argv[optind + 1], 10)) { - fprintf(stderr, "Illegal \"index\"\n"); - free_opts(opts); - return -1; - } - iok++; - - optind += 2; - } - } - - if (!ok && !iok) { - fprintf(stderr," ipt Parser BAD!! (%s)\n", *argv); - return -1; - } - - /* check that we passed the correct parameters to the target */ - if (m) - m->final_check(m->tflags); - - { - struct tcmsg *t = NLMSG_DATA(n); - if (t->tcm_parent != TC_H_ROOT - && t->tcm_parent == TC_H_MAJ(TC_H_INGRESS)) { - hook = NF_IP_PRE_ROUTING; - } else { - hook = NF_IP_POST_ROUTING; - } - } - - tail = NLMSG_TAIL(n); - addattr_l(n, MAX_MSG, tca_id, NULL, 0); - fprintf(stdout, "tablename: %s hook: %s\n ", tname, ipthooks[hook]); - fprintf(stdout, "\ttarget: "); - - if (m) - m->print(NULL, m->t, 0); - fprintf(stdout, " index %d\n", index); - - if (strlen(tname) > 16) { - size = 16; - k[15] = 0; - } else { - size = 1 + strlen(tname); - } - strncpy(k, tname, size); - - addattr_l(n, MAX_MSG, TCA_IPT_TABLE, k, size); - addattr_l(n, MAX_MSG, TCA_IPT_HOOK, &hook, 4); - addattr_l(n, MAX_MSG, TCA_IPT_INDEX, &index, 4); - if (m) - addattr_l(n, MAX_MSG, TCA_IPT_TARG, m->t, m->t->u.target_size); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - - argc -= optind; - argv += optind; - *argc_p = rargc - iargc; - *argv_p = argv; - - optind = 1; - free_opts(opts); - - return 0; - -} - -static int -print_ipt(struct action_util *au,FILE * f, struct rtattr *arg) -{ - struct rtattr *tb[TCA_IPT_MAX + 1]; - struct ipt_entry_target *t = NULL; - - if (arg == NULL) - return -1; - - parse_rtattr_nested(tb, TCA_IPT_MAX, arg); - - if (tb[TCA_IPT_TABLE] == NULL) { - fprintf(f, "[NULL ipt table name ] assuming mangle "); - } else { - fprintf(f, "tablename: %s ", - (char *) RTA_DATA(tb[TCA_IPT_TABLE])); - } - - if (tb[TCA_IPT_HOOK] == NULL) { - fprintf(f, "[NULL ipt hook name ]\n "); - return -1; - } else { - __u32 hook; - hook = *(__u32 *) RTA_DATA(tb[TCA_IPT_HOOK]); - fprintf(f, " hook: %s \n", ipthooks[hook]); - } - - if (tb[TCA_IPT_TARG] == NULL) { - fprintf(f, "\t[NULL ipt target parameters ] \n"); - return -1; - } else { - struct iptables_target *m = NULL; - t = RTA_DATA(tb[TCA_IPT_TARG]); - m = get_target_name(t->u.user.name); - if (NULL != m) { - if (0 > build_st(m, t)) { - fprintf(stderr, " %s error \n", m->name); - return -1; - } - - opts = - merge_options(opts, m->extra_opts, - &m->option_offset); - } else { - fprintf(stderr, " failed to find target %s\n\n", - t->u.user.name); - return -1; - } - fprintf(f, "\ttarget "); - m->print(NULL, m->t, 0); - if (tb[TCA_IPT_INDEX] == NULL) { - fprintf(f, " [NULL ipt target index ]\n"); - } else { - __u32 index; - index = *(__u32 *) RTA_DATA(tb[TCA_IPT_INDEX]); - fprintf(f, " \n\tindex %d", index); - } - - if (tb[TCA_IPT_CNT]) { - struct tc_cnt *c = RTA_DATA(tb[TCA_IPT_CNT]);; - fprintf(f, " ref %d bind %d", c->refcnt, c->bindcnt); - } - if (show_stats) { - if (tb[TCA_IPT_TM]) { - struct tcf_t *tm = RTA_DATA(tb[TCA_IPT_TM]); - print_tm(f,tm); - } - } - fprintf(f, " \n"); - - } - free_opts(opts); - - return 0; -} - -struct action_util ipt_action_util = { - .id = "ipt", - .parse_aopt = parse_ipt, - .print_aopt = print_ipt, -}; - diff --git a/tc/m_mirred.c b/tc/m_mirred.c deleted file mode 100644 index cbfea84..0000000 --- a/tc/m_mirred.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * m_egress.c ingress/egress packet mirror/redir actions module - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim (hadi@cyberus.ca) - * - * TODO: Add Ingress support - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include "utils.h" -#include "tc_util.h" -#include "tc_common.h" -#include <linux/tc_act/tc_mirred.h> - -int mirred_d = 1; - -static void -explain(void) -{ - fprintf(stderr, "Usage: mirred <DIRECTION> <ACTION> [index INDEX] <dev DEVICENAME> \n"); - fprintf(stderr, "where: \n"); - fprintf(stderr, "DIRECTION := <ingress | egress>\n"); - fprintf(stderr, "aCTION := <mirror | redirect>\n"); - fprintf(stderr, " : INDEX is the specific policy instance id\n"); - fprintf(stderr, " : DEVICENAME is the devicename \n"); -} - -#define usage() return(-1) - -char *mirred_n2a(int action) -{ - switch (action) { - case TCA_EGRESS_REDIR: - return "Egress Redirect"; - case TCA_INGRESS_REDIR: - return "Ingress Redirect"; - case TCA_EGRESS_MIRROR: - return "Egress Mirror"; - case TCA_INGRESS_MIRROR: - return "Ingress Mirror"; - default: - return "unknown"; - } -} - -int -parse_egress(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) -{ - - int argc = *argc_p; - char **argv = *argv_p; - int ok = 0, iok = 0, mirror=0,redir=0; - struct tc_mirred p; - struct rtattr *tail; - char d[16]; - - memset(d,0,sizeof(d)-1); - memset(&p,0,sizeof(struct tc_mirred)); - - while (argc > 0) { - - if (matches(*argv, "action") == 0) { - break; - } else if (matches(*argv, "egress") == 0) { - NEXT_ARG(); - ok++; - continue; - } else { - - if (matches(*argv, "index") == 0) { - NEXT_ARG(); - if (get_u32(&p.index, *argv, 10)) { - fprintf(stderr, "Illegal \"index\"\n"); - return -1; - } - iok++; - if (!ok) { - argc--; - argv++; - break; - } - } else if(!ok) { - fprintf(stderr, "was expecting egress (%s)\n", *argv); - break; - - } else if (!mirror && matches(*argv, "mirror") == 0) { - mirror=1; - if (redir) { - fprintf(stderr, "Cant have both mirror and redir\n"); - return -1; - } - p.eaction = TCA_EGRESS_MIRROR; - p.action = TC_ACT_PIPE; - ok++; - } else if (!redir && matches(*argv, "redirect") == 0) { - redir=1; - if (mirror) { - fprintf(stderr, "Cant have both mirror and redir\n"); - return -1; - } - p.eaction = TCA_EGRESS_REDIR; - p.action = TC_ACT_STOLEN; - ok++; - } else if ((redir || mirror) && matches(*argv, "dev") == 0) { - NEXT_ARG(); - if (strlen(d)) - duparg("dev", *argv); - - strncpy(d, *argv, sizeof(d)-1); - argc--; - argv++; - - break; - - } - } - - NEXT_ARG(); - } - - if (!ok && !iok) { - explain(); - return -1; - } - - - - if (d[0]) { - int idx; - ll_init_map(&rth); - - if ((idx = ll_name_to_index(d)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return -1; - } - - p.ifindex = idx; - } - - - if (argc && p.eaction == TCA_EGRESS_MIRROR) { - - if (matches(*argv, "reclassify") == 0) { - p.action = TC_POLICE_RECLASSIFY; - NEXT_ARG(); - } else if (matches(*argv, "pipe") == 0) { - p.action = TC_POLICE_PIPE; - NEXT_ARG(); - } else if (matches(*argv, "drop") == 0 || - matches(*argv, "shot") == 0) { - p.action = TC_POLICE_SHOT; - NEXT_ARG(); - } else if (matches(*argv, "continue") == 0) { - p.action = TC_POLICE_UNSPEC; - NEXT_ARG(); - } else if (matches(*argv, "pass") == 0) { - p.action = TC_POLICE_OK; - NEXT_ARG(); - } - - } - - if (argc) { - if (iok && matches(*argv, "index") == 0) { - fprintf(stderr, "mirred: Illegal double index\n"); - return -1; - } else { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); - if (get_u32(&p.index, *argv, 10)) { - fprintf(stderr, "mirred: Illegal \"index\"\n"); - return -1; - } - argc--; - argv++; - } - } - } - - if (mirred_d) - fprintf(stdout, "Action %d device %s ifindex %d\n",p.action, d,p.ifindex); - - tail = NLMSG_TAIL(n); - addattr_l(n, MAX_MSG, tca_id, NULL, 0); - addattr_l(n, MAX_MSG, TCA_MIRRED_PARMS, &p, sizeof (p)); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - - *argc_p = argc; - *argv_p = argv; - return 0; -} - - -int -parse_mirred(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) -{ - - int argc = *argc_p; - char **argv = *argv_p; - - if (argc < 0) { - fprintf(stderr,"mirred bad arguement count %d\n", argc); - return -1; - } - - if (matches(*argv, "mirred") == 0) { - NEXT_ARG(); - } else { - fprintf(stderr,"mirred bad arguement %s\n", *argv); - return -1; - } - - - if (matches(*argv, "egress") == 0 || matches(*argv, "index") == 0) { - int ret = parse_egress(a, &argc, &argv, tca_id, n); - if (ret == 0) { - *argc_p = argc; - *argv_p = argv; - return 0; - } - - } else if (matches(*argv, "ingress") == 0) { - fprintf(stderr,"mirred ingress not supported at the moment\n"); - - } else { - fprintf(stderr,"mirred not supported %s\n", *argv); - } - - return -1; - -} - -int -print_mirred(struct action_util *au,FILE * f, struct rtattr *arg) -{ - struct tc_mirred *p; - struct rtattr *tb[TCA_MIRRED_MAX + 1]; - const char *dev; - SPRINT_BUF(b1); - - if (arg == NULL) - return -1; - - parse_rtattr_nested(tb, TCA_MIRRED_MAX, arg); - - if (tb[TCA_MIRRED_PARMS] == NULL) { - fprintf(f, "[NULL mirred parameters]"); - return -1; - } - p = RTA_DATA(tb[TCA_MIRRED_PARMS]); - - /* - ll_init_map(&rth); - */ - - - if ((dev = ll_index_to_name(p->ifindex)) == 0) { - fprintf(stderr, "Cannot find device %d\n", p->ifindex); - return -1; - } - - fprintf(f, "mirred (%s to device %s) %s", mirred_n2a(p->eaction), dev,action_n2a(p->action, b1, sizeof (b1))); - - fprintf(f, "\n "); - fprintf(f, "\tindex %d ref %d bind %d",p->index,p->refcnt,p->bindcnt); - - if (show_stats) { - if (tb[TCA_MIRRED_TM]) { - struct tcf_t *tm = RTA_DATA(tb[TCA_MIRRED_TM]); - print_tm(f,tm); - } - } - fprintf(f, "\n "); - return 0; -} - -struct action_util mirred_action_util = { - .id = "mirred", - .parse_aopt = parse_mirred, - .print_aopt = print_mirred, -}; diff --git a/tc/m_pedit.c b/tc/m_pedit.c deleted file mode 100644 index acfa581..0000000 --- a/tc/m_pedit.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * m_pedit.c generic packet editor actions module - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim (hadi@cyberus.ca) - * - * TODO: - * 1) Big endian broken in some spots - * 2) A lot of this stuff was added on the fly; get a big double-double - * and clean it up at some point. - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <dlfcn.h> -#include "utils.h" -#include "tc_util.h" -#include "m_pedit.h" - -static struct m_pedit_util *pedit_list; -int pedit_debug = 1; - -static void -p_explain(void) -{ - fprintf(stderr, "Usage: ... pedit <MUNGE>\n"); - fprintf(stderr, - "Where: MUNGE := <RAW>|<LAYERED>\n" - "<RAW>:= <OFFSETC>[ATC]<CMD>\n " - "OFFSETC:= offset <offval> <u8|u16|u32>\n " - "ATC:= at <atval> offmask <maskval> shift <shiftval>\n " - "NOTE: offval is byte offset, must be multiple of 4\n " - "NOTE: maskval is a 32 bit hex number\n " - "NOTE: shiftval is a is a shift value\n " - "CMD:= clear | invert | set <setval>| retain\n " - "<LAYERED>:= ip <ipdata> | ip6 <ip6data> \n " - " | udp <udpdata> | tcp <tcpdata> | icmp <icmpdata> \n" - "For Example usage look at the examples directory"); - -} - -#define usage() return(-1) - -static int -pedit_parse_nopopt (int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - int argc = *argc_p; - char **argv = *argv_p; - - if (argc) { - fprintf(stderr, "Unknown action hence option \"%s\" is unparsable\n", *argv); - return -1; - } - - return 0; - -} - -struct m_pedit_util -*get_pedit_kind(char *str) -{ - static void *pBODY; - void *dlh; - char buf[256]; - struct m_pedit_util *p; - - for (p = pedit_list; p; p = p->next) { - if (strcmp(p->id, str) == 0) - return p; - } - - snprintf(buf, sizeof(buf), "p_%s.so", str); - dlh = dlopen(buf, RTLD_LAZY); - if (dlh == NULL) { - dlh = pBODY; - if (dlh == NULL) { - dlh = pBODY = dlopen(NULL, RTLD_LAZY); - if (dlh == NULL) - goto noexist; - } - } - - snprintf(buf, sizeof(buf), "p_pedit_%s", str); - p = dlsym(dlh, buf); - if (p == NULL) - goto noexist; - -reg: - p->next = pedit_list; - pedit_list = p; - return p; - -noexist: - p = malloc(sizeof(*p)); - if (p) { - memset(p, 0, sizeof(*p)); - strncpy(p->id, str, sizeof(p->id)-1); - p->parse_peopt = pedit_parse_nopopt; - goto reg; - } - return p; -} - -int -pack_key(struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - int hwm = sel->nkeys; - - if (hwm >= MAX_OFFS) - return -1; - - if (tkey->off % 4) { - fprintf(stderr, "offsets MUST be in 32 bit boundaries\n"); - return -1; - } - - sel->keys[hwm].val = tkey->val; - sel->keys[hwm].mask = tkey->mask; - sel->keys[hwm].off = tkey->off; - sel->keys[hwm].at = tkey->at; - sel->keys[hwm].offmask = tkey->offmask; - sel->keys[hwm].shift = tkey->shift; - sel->nkeys++; - return 0; -} - - -int -pack_key32(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - if (tkey->off > (tkey->off & ~3)) { - fprintf(stderr, - "pack_key32: 32 bit offsets must begin in 32bit boundaries\n"); - return -1; - } - - tkey->val = htonl(tkey->val & retain); - tkey->mask = htonl(tkey->mask | ~retain); - /* jamal remove this - it is not necessary given the if check above */ - tkey->off &= ~3; - return pack_key(sel,tkey); -} - -int -pack_key16(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - int ind = 0, stride = 0; - __u32 m[4] = {0xFFFF0000,0xFF0000FF,0x0000FFFF}; - - if (0 > tkey->off) { - ind = tkey->off + 1; - if (0 > ind) - ind = -1*ind; - } else { - ind = tkey->off; - } - - if (tkey->val > 0xFFFF || tkey->mask > 0xFFFF) { - fprintf(stderr, "pack_key16 bad value\n"); - return -1; - } - - ind = tkey->off & 3; - - if (0 > ind || 2 < ind) { - fprintf(stderr, "pack_key16 bad index value %d\n",ind); - return -1; - } - - stride = 8 * ind; - tkey->val = htons(tkey->val); - if (stride > 0) { - tkey->val <<= stride; - tkey->mask <<= stride; - retain <<= stride; - } - tkey->mask = retain|m[ind]; - - tkey->off &= ~3; - - if (pedit_debug) - printf("pack_key16: Final val %08x mask %08x \n",tkey->val,tkey->mask); - return pack_key(sel,tkey); - -} - -int -pack_key8(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - int ind = 0, stride = 0; - __u32 m[4] = {0xFFFFFF00,0xFFFF00FF,0xFF00FFFF,0x00FFFFFF}; - - if (0 > tkey->off) { - ind = tkey->off + 1; - if (0 > ind) - ind = -1*ind; - } else { - ind = tkey->off; - } - - if (tkey->val > 0xFF || tkey->mask > 0xFF) { - fprintf(stderr, "pack_key8 bad value (val %x mask %x\n", tkey->val, tkey->mask); - return -1; - } - - ind = tkey->off & 3; - stride = 8 * ind; - tkey->val <<= stride; - tkey->mask <<= stride; - retain <<= stride; - tkey->mask = retain|m[ind]; - tkey->off &= ~3; - - if (pedit_debug) - printf("pack_key8: Final word off %d val %08x mask %08x \n",tkey->off , tkey->val,tkey->mask); - return pack_key(sel,tkey); -} - -int -parse_val(int *argc_p, char ***argv_p, __u32 * val, int type) -{ - int argc = *argc_p; - char **argv = *argv_p; - - if (argc <= 0) - return -1; - - if (TINT == type) - return get_integer((int *) val, *argv, 0); - - if (TU32 == type) - return get_u32(val, *argv, 0); - - if (TIPV4 == type) { - inet_prefix addr; - if (get_prefix_1(&addr, *argv, AF_INET)) { - return -1; - } - *val=addr.data[0]; - return 0; - } - if (TIPV6 == type) { - /* not implemented yet */ - return -1; - } - - return -1; -} - -int -parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - __u32 mask = 0, val = 0; - __u32 o = 0xFF; - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - - if (argc <= 0) - return -1; - - if (pedit_debug) - printf("parse_cmd argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len); - - if (len == 2) - o = 0xFFFF; - if (len == 4) - o = 0xFFFFFFFF; - - if (matches(*argv, "invert") == 0) { - retain = val = mask = o; - } else if (matches(*argv, "set") == 0) { - NEXT_ARG(); - if (parse_val(&argc, &argv, &val, type)) - return -1; - } else if (matches(*argv, "preserve") == 0) { - retain = mask = o; - } else { - if (matches(*argv, "clear") != 0) - return -1; - } - - argc--; argv++; - - if (argc && matches(*argv, "retain") == 0) { - NEXT_ARG(); - if (parse_val(&argc, &argv, &retain, TU32)) - return -1; - argc--; argv++; - } - - tkey->val = val; - - if (len == 1) { - tkey->mask = 0xFF; - res = pack_key8(retain,sel,tkey); - goto done; - } - if (len == 2) { - tkey->mask = mask; - res = pack_key16(retain,sel,tkey); - goto done; - } - if (len == 4) { - tkey->mask = mask; - res = pack_key32(retain,sel,tkey); - goto done; - } - - return -1; -done: - if (pedit_debug) - printf("parse_cmd done argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len); - *argc_p = argc; - *argv_p = argv; - return res; - -} - -int -parse_offset(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - int off; - __u32 len, retain; - int argc = *argc_p; - char **argv = *argv_p; - int res = -1; - - if (argc <= 0) - return -1; - - if (get_integer(&off, *argv, 0)) - return -1; - tkey->off = off; - - argc--; - argv++; - - if (argc <= 0) - return -1; - - - if (matches(*argv, "u32") == 0) { - len = 4; - retain = 0xFFFFFFFF; - goto done; - } - if (matches(*argv, "u16") == 0) { - len = 2; - retain = 0x0; - goto done; - } - if (matches(*argv, "u8") == 0) { - len = 1; - retain = 0x0; - goto done; - } - - return -1; - -done: - - NEXT_ARG(); - - /* [at <someval> offmask <maskval> shift <shiftval>] */ - if (matches(*argv, "at") == 0) { - - __u32 atv=0,offmask=0x0,shift=0; - - NEXT_ARG(); - if (get_u32(&atv, *argv, 0)) - return -1; - tkey->at = atv; - - NEXT_ARG(); - - if (get_u32(&offmask, *argv, 16)) - return -1; - tkey->offmask = offmask; - - NEXT_ARG(); - - if (get_u32(&shift, *argv, 0)) - return -1; - tkey->shift = shift; - - NEXT_ARG(); - } - - res = parse_cmd(&argc, &argv, len, TU32,retain,sel,tkey); - - *argc_p = argc; - *argv_p = argv; - return res; -} - -int -parse_munge(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel) -{ - struct tc_pedit_key tkey; - int argc = *argc_p; - char **argv = *argv_p; - int res = -1; - - if (argc <= 0) - return -1; - - memset(&tkey, 0, sizeof(tkey)); - - if (matches(*argv, "offset") == 0) { - NEXT_ARG(); - res = parse_offset(&argc, &argv,sel,&tkey); - goto done; -#if jamal - } else if (strcmp(*argv, "help") == 0) { - p_explain(); - return -1; -#endif - } else { - char k[16]; - struct m_pedit_util *p = NULL; - - strncpy(k, *argv, sizeof (k) - 1); - - if (argc > 0 ) { - p = get_pedit_kind(k); - if (NULL == p) - goto bad_val; - res = p->parse_peopt(&argc, &argv, sel,&tkey); - if (res < 0) { - fprintf(stderr,"bad pedit parsing\n"); - goto bad_val; - } - goto done; - } - } - -bad_val: - return -1; - -done: - - *argc_p = argc; - *argv_p = argv; - return res; -} - -int -parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) -{ - struct { - struct tc_pedit_sel sel; - struct tc_pedit_key keys[MAX_OFFS]; - } sel; - - int argc = *argc_p; - char **argv = *argv_p; - int ok = 0, iok = 0; - struct rtattr *tail; - - memset(&sel, 0, sizeof(sel)); - - while (argc > 0) { - if (pedit_debug > 1) - fprintf(stderr, "while pedit (%d:%s)\n",argc, *argv); - if (matches(*argv, "pedit") == 0) { - NEXT_ARG(); - ok++; - continue; - } else if (matches(*argv, "munge") == 0) { - if (!ok) { - fprintf(stderr, "Illegal pedit construct (%s) \n", *argv); - p_explain(); - return -1; - } - NEXT_ARG(); - if (parse_munge(&argc, &argv,&sel.sel)) { - fprintf(stderr, "Illegal pedit construct (%s) \n", *argv); - p_explain(); - return -1; - } - ok++; - } else { - break; - } - - } - - if (!ok) { - p_explain(); - return -1; - } - - if (argc) { - if (matches(*argv, "reclassify") == 0) { - sel.sel.action = TC_ACT_RECLASSIFY; - NEXT_ARG(); - } else if (matches(*argv, "pipe") == 0) { - sel.sel.action = TC_ACT_PIPE; - NEXT_ARG(); - } else if (matches(*argv, "drop") == 0 || - matches(*argv, "shot") == 0) { - sel.sel.action = TC_ACT_SHOT; - NEXT_ARG(); - } else if (matches(*argv, "continue") == 0) { - sel.sel.action = TC_ACT_UNSPEC; - NEXT_ARG(); - } else if (matches(*argv, "pass") == 0) { - sel.sel.action = TC_ACT_OK; - NEXT_ARG(); - } - } - - if (argc) { - if (matches(*argv, "index") == 0) { - NEXT_ARG(); - if (get_u32(&sel.sel.index, *argv, 10)) { - fprintf(stderr, "Pedit: Illegal \"index\"\n"); - return -1; - } - argc--; - argv++; - iok++; - } - } - - tail = NLMSG_TAIL(n); - addattr_l(n, MAX_MSG, tca_id, NULL, 0); - addattr_l(n, MAX_MSG, TCA_PEDIT_PARMS,&sel, sizeof(sel.sel)+sel.sel.nkeys*sizeof(struct tc_pedit_key)); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - - *argc_p = argc; - *argv_p = argv; - return 0; -} - -int -print_pedit(struct action_util *au,FILE * f, struct rtattr *arg) -{ - struct tc_pedit_sel *sel; - struct rtattr *tb[TCA_PEDIT_MAX + 1]; - SPRINT_BUF(b1); - - if (arg == NULL) - return -1; - - parse_rtattr_nested(tb, TCA_PEDIT_MAX, arg); - - if (tb[TCA_PEDIT_PARMS] == NULL) { - fprintf(f, "[NULL pedit parameters]"); - return -1; - } - sel = RTA_DATA(tb[TCA_PEDIT_PARMS]); - - fprintf(f, " pedit action %s keys %d\n ", action_n2a(sel->action, b1, sizeof (b1)),sel->nkeys); - fprintf(f, "\t index %d ref %d bind %d", sel->index,sel->refcnt, sel->bindcnt); - - if (show_stats) { - if (tb[TCA_PEDIT_TM]) { - struct tcf_t *tm = RTA_DATA(tb[TCA_PEDIT_TM]); - print_tm(f,tm); - } - } - if (sel->nkeys) { - int i; - struct tc_pedit_key *key = sel->keys; - - for (i=0; i<sel->nkeys; i++, key++) { - fprintf(f, "\n\t key #%d",i); - fprintf(f, " at %d: val %08x mask %08x", - (unsigned int)key->off, - (unsigned int)ntohl(key->val), - (unsigned int)ntohl(key->mask)); - } - } else { - fprintf(f, "\npedit %x keys %d is not LEGIT", sel->index,sel->nkeys); - } - - - fprintf(f, "\n "); - return 0; -} - -int -pedit_print_xstats(struct action_util *au, FILE *f, struct rtattr *xstats) -{ - return 0; -} - -struct action_util pedit_action_util = { - .id = "pedit", - .parse_aopt = parse_pedit, - .print_aopt = print_pedit, -}; diff --git a/tc/m_pedit.h b/tc/m_pedit.h deleted file mode 100644 index 0a6d24e..0000000 --- a/tc/m_pedit.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * m_pedit.h generic packet editor actions module - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim (hadi@cyberus.ca) - * - */ - -#ifndef _ACT_PEDIT_H_ -#define _ACT_PEDIT_H_ 1 - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include "utils.h" -#include "tc_util.h" -#include <linux/tc_act/tc_pedit.h> - -#define MAX_OFFS 128 - -#define TIPV4 1 -#define TIPV6 2 -#define TINT 3 -#define TU32 4 - -#define RU32 0xFFFFFFFF -#define RU16 0xFFFF -#define RU8 0xFF - -#define PEDITKINDSIZ 16 - -struct m_pedit_util -{ - struct m_pedit_util *next; - char id[PEDITKINDSIZ]; - int (*parse_peopt)(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey); -}; - - -extern int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey); -extern int pack_key(struct tc_pedit_sel *sel,struct tc_pedit_key *tkey); -extern int pack_key32(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey); -extern int pack_key16(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey); -extern int pack_key8(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey); -extern int parse_val(int *argc_p, char ***argv_p, __u32 * val, int type); -extern int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey); -extern int parse_offset(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey); -int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n); -extern int print_pedit(struct action_util *au,FILE * f, struct rtattr *arg); -extern int pedit_print_xstats(struct action_util *au, FILE *f, struct rtattr *xstats); - -#endif diff --git a/tc/m_police.c b/tc/m_police.c deleted file mode 100644 index 71adb59..0000000 --- a/tc/m_police.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * m_police.c Parse/print policing module options. - * - * This program is free software; you can u32istribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * FIXES: 19990619 - J Hadi Salim (hadi@cyberus.ca) - * simple addattr packaging fix. - * 2002: J Hadi Salim - Add tc action extensions syntax - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - -struct action_util police_action_util = { - .id = "police", - .parse_aopt = act_parse_police, - .print_aopt = print_police, -}; - -static void explain(void) -{ - fprintf(stderr, "Usage: ... police rate BPS burst BYTES[/BYTES] [ mtu BYTES[/BYTES] ]\n"); - fprintf(stderr, " [ peakrate BPS ] [ avrate BPS ]\n"); - fprintf(stderr, " [ ACTIONTERM ]\n"); - fprintf(stderr, "Old Syntax ACTIONTERM := action <EXCEEDACT>[/NOTEXCEEDACT] \n"); - fprintf(stderr, "New Syntax ACTIONTERM := conform-exceed <EXCEEDACT>[/NOTEXCEEDACT] \n"); - fprintf(stderr, "Where: *EXCEEDACT := pipe | ok | reclassify | drop | continue \n"); - fprintf(stderr, "Where: pipe is only valid for new syntax \n"); -} - -static void explain1(char *arg) -{ - fprintf(stderr, "Illegal \"%s\"\n", arg); -} - -#define usage() return(-1) - - -char *police_action_n2a(int action, char *buf, int len) -{ - switch (action) { - case -1: - return "continue"; - break; - case TC_POLICE_OK: - return "pass"; - break; - case TC_POLICE_SHOT: - return "drop"; - break; - case TC_POLICE_RECLASSIFY: - return "reclassify"; - case TC_POLICE_PIPE: - return "pipe"; - default: - snprintf(buf, len, "%d", action); - return buf; - } -} - -int police_action_a2n(char *arg, int *result) -{ - int res; - - if (matches(arg, "continue") == 0) - res = -1; - else if (matches(arg, "drop") == 0) - res = TC_POLICE_SHOT; - else if (matches(arg, "shot") == 0) - res = TC_POLICE_SHOT; - else if (matches(arg, "pass") == 0) - res = TC_POLICE_OK; - else if (strcmp(arg, "ok") == 0) - res = TC_POLICE_OK; - else if (matches(arg, "reclassify") == 0) - res = TC_POLICE_RECLASSIFY; - else if (matches(arg, "pipe") == 0) - res = TC_POLICE_PIPE; - else { - char dummy; - if (sscanf(arg, "%d%c", &res, &dummy) != 1) - return -1; - } - *result = res; - return 0; -} - - -int get_police_result(int *action, int *result, char *arg) -{ - char *p = strchr(arg, '/'); - - if (p) - *p = 0; - - if (police_action_a2n(arg, action)) { - if (p) - *p = '/'; - return -1; - } - - if (p) { - *p = '/'; - if (police_action_a2n(p+1, result)) - return -1; - } - return 0; -} - - -int act_parse_police(struct action_util *a,int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) -{ - int argc = *argc_p; - char **argv = *argv_p; - int res = -1; - int ok=0; - struct tc_police p; - __u32 rtab[256]; - __u32 ptab[256]; - __u32 avrate = 0; - int presult = 0; - unsigned buffer=0, mtu=0, mpu=0; - int Rcell_log=-1, Pcell_log = -1; - struct rtattr *tail; - - memset(&p, 0, sizeof(p)); - p.action = TC_POLICE_RECLASSIFY; - - if (a) /* new way of doing things */ - NEXT_ARG(); - - if (argc <= 0) - return -1; - - while (argc > 0) { - - if (matches(*argv, "index") == 0) { - NEXT_ARG(); - if (get_u32(&p.index, *argv, 10)) { - fprintf(stderr, "Illegal \"index\"\n"); - return -1; - } - } else if (matches(*argv, "burst") == 0 || - strcmp(*argv, "buffer") == 0 || - strcmp(*argv, "maxburst") == 0) { - NEXT_ARG(); - if (buffer) { - fprintf(stderr, "Double \"buffer/burst\" spec\n"); - return -1; - } - if (get_size_and_cell(&buffer, &Rcell_log, *argv) < 0) { - explain1("buffer"); - return -1; - } - } else if (strcmp(*argv, "mtu") == 0 || - strcmp(*argv, "minburst") == 0) { - NEXT_ARG(); - if (mtu) { - fprintf(stderr, "Double \"mtu/minburst\" spec\n"); - return -1; - } - if (get_size_and_cell(&mtu, &Pcell_log, *argv) < 0) { - explain1("mtu"); - return -1; - } - } else if (strcmp(*argv, "mpu") == 0) { - NEXT_ARG(); - if (mpu) { - fprintf(stderr, "Double \"mpu\" spec\n"); - return -1; - } - if (get_size(&mpu, *argv)) { - explain1("mpu"); - return -1; - } - } else if (strcmp(*argv, "rate") == 0) { - NEXT_ARG(); - if (p.rate.rate) { - fprintf(stderr, "Double \"rate\" spec\n"); - return -1; - } - if (get_rate(&p.rate.rate, *argv)) { - explain1("rate"); - return -1; - } - } else if (strcmp(*argv, "avrate") == 0) { - NEXT_ARG(); - if (avrate) { - fprintf(stderr, "Double \"avrate\" spec\n"); - return -1; - } - if (get_rate(&avrate, *argv)) { - explain1("avrate"); - return -1; - } - } else if (matches(*argv, "peakrate") == 0) { - NEXT_ARG(); - if (p.peakrate.rate) { - fprintf(stderr, "Double \"peakrate\" spec\n"); - return -1; - } - if (get_rate(&p.peakrate.rate, *argv)) { - explain1("peakrate"); - return -1; - } - } else if (matches(*argv, "reclassify") == 0) { - p.action = TC_POLICE_RECLASSIFY; - } else if (matches(*argv, "drop") == 0 || - matches(*argv, "shot") == 0) { - p.action = TC_POLICE_SHOT; - } else if (matches(*argv, "continue") == 0) { - p.action = TC_POLICE_UNSPEC; - } else if (matches(*argv, "pass") == 0) { - p.action = TC_POLICE_OK; - } else if (matches(*argv, "pipe") == 0) { - p.action = TC_POLICE_PIPE; - } else if (strcmp(*argv, "conform-exceed") == 0) { - NEXT_ARG(); - if (get_police_result(&p.action, &presult, *argv)) { - fprintf(stderr, "Illegal \"action\"\n"); - return -1; - } - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - break; - } - ok++; - argc--; argv++; - } - - if (!ok) - return -1; - - if (p.rate.rate && !buffer) { - fprintf(stderr, "\"burst\" requires \"rate\".\n"); - return -1; - } - if (p.peakrate.rate) { - if (!p.rate.rate) { - fprintf(stderr, "\"peakrate\" requires \"rate\".\n"); - return -1; - } - if (!mtu) { - fprintf(stderr, "\"mtu\" is required, if \"peakrate\" is requested.\n"); - return -1; - } - } - - if (p.rate.rate) { - if ((Rcell_log = tc_calc_rtable(p.rate.rate, rtab, Rcell_log, mtu, mpu)) < 0) { - fprintf(stderr, "TBF: failed to calculate rate table.\n"); - return -1; - } - p.burst = tc_calc_xmittime(p.rate.rate, buffer); - p.rate.cell_log = Rcell_log; - p.rate.mpu = mpu; - } - p.mtu = mtu; - if (p.peakrate.rate) { - if ((Pcell_log = tc_calc_rtable(p.peakrate.rate, ptab, Pcell_log, mtu, mpu)) < 0) { - fprintf(stderr, "POLICE: failed to calculate peak rate table.\n"); - return -1; - } - p.peakrate.cell_log = Pcell_log; - p.peakrate.mpu = mpu; - } - - tail = NLMSG_TAIL(n); - addattr_l(n, MAX_MSG, tca_id, NULL, 0); - addattr_l(n, MAX_MSG, TCA_POLICE_TBF, &p, sizeof(p)); - if (p.rate.rate) - addattr_l(n, MAX_MSG, TCA_POLICE_RATE, rtab, 1024); - if (p.peakrate.rate) - addattr_l(n, MAX_MSG, TCA_POLICE_PEAKRATE, ptab, 1024); - if (avrate) - addattr32(n, MAX_MSG, TCA_POLICE_AVRATE, avrate); - if (presult) - addattr32(n, MAX_MSG, TCA_POLICE_RESULT, presult); - - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - res = 0; - - *argc_p = argc; - *argv_p = argv; - return res; -} - -int parse_police(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) -{ - return act_parse_police(NULL,argc_p,argv_p,tca_id,n); -} - -int -print_police(struct action_util *a, FILE *f, struct rtattr *arg) -{ - SPRINT_BUF(b1); - struct tc_police *p; - struct rtattr *tb[TCA_POLICE_MAX+1]; - unsigned buffer; - - if (arg == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_POLICE_MAX, arg); - - if (tb[TCA_POLICE_TBF] == NULL) { - fprintf(f, "[NULL police tbf]"); - return 0; - } -#ifndef STOOPID_8BYTE - if (RTA_PAYLOAD(tb[TCA_POLICE_TBF]) < sizeof(*p)) { - fprintf(f, "[truncated police tbf]"); - return -1; - } -#endif - p = RTA_DATA(tb[TCA_POLICE_TBF]); - - fprintf(f, " police 0x%x ", p->index); - fprintf(f, "rate %s ", sprint_rate(p->rate.rate, b1)); - buffer = ((double)p->rate.rate*tc_core_tick2usec(p->burst))/1000000; - fprintf(f, "burst %s ", sprint_size(buffer, b1)); - fprintf(f, "mtu %s ", sprint_size(p->mtu, b1)); - if (show_raw) - fprintf(f, "[%08x] ", p->burst); - if (p->peakrate.rate) - fprintf(f, "peakrate %s ", sprint_rate(p->peakrate.rate, b1)); - if (tb[TCA_POLICE_AVRATE]) - fprintf(f, "avrate %s ", sprint_rate(*(__u32*)RTA_DATA(tb[TCA_POLICE_AVRATE]), b1)); - fprintf(f, "action %s", police_action_n2a(p->action, b1, sizeof(b1))); - if (tb[TCA_POLICE_RESULT]) { - fprintf(f, "/%s ", police_action_n2a(*(int*)RTA_DATA(tb[TCA_POLICE_RESULT]), b1, sizeof(b1))); - } else - fprintf(f, " "); - fprintf(f, "\nref %d bind %d\n",p->refcnt, p->bindcnt); - - return 0; -} - -int -tc_print_police(FILE *f, struct rtattr *arg) { - return print_police(&police_action_util,f,arg); -} diff --git a/tc/p_icmp.c b/tc/p_icmp.c deleted file mode 100644 index f9ddbe3..0000000 --- a/tc/p_icmp.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * m_pedit_icmp.c packet editor: ICMP header - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim (hadi@cyberus.ca) - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include "utils.h" -#include "tc_util.h" -#include "m_pedit.h" - - -static int -parse_icmp(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - int res = -1; -#if 0 - int argc = *argc_p; - char **argv = *argv_p; - - if (argc < 2) - return -1; - - if (strcmp(*argv, "type") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, 0); - goto done; - } - if (strcmp(*argv, "code") == 0) { - NEXT_ARG(); - res = parse_u8(&argc, &argv, 1); - goto done; - } - return -1; - - done: - *argc_p = argc; - *argv_p = argv; -#endif - return res; -} - -struct m_pedit_util p_pedit_icmp = { - NULL, - "icmp", - parse_icmp, -}; diff --git a/tc/p_ip.c b/tc/p_ip.c deleted file mode 100644 index 1b2a440..0000000 --- a/tc/p_ip.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * m_pedit.c packet editor: IPV4/6 header - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim (hadi@cyberus.ca) - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include "utils.h" -#include "tc_util.h" -#include "m_pedit.h" - -static int -parse_ip(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - int res = -1; - int argc = *argc_p; - char **argv = *argv_p; - - if (argc < 2) - return -1; - - if (strcmp(*argv, "src") == 0) { - NEXT_ARG(); - tkey->off = 12; - res = parse_cmd(&argc, &argv, 4, TIPV4,RU32,sel,tkey); - goto done; - } - if (strcmp(*argv, "dst") == 0) { - NEXT_ARG(); - tkey->off = 16; - res = parse_cmd(&argc, &argv, 4, TIPV4,RU32,sel,tkey); - goto done; - } - /* jamal - look at these and make them either old or new - ** scheme given diffserv - ** dont forget the CE bit - */ - if (strcmp(*argv, "tos") == 0 || matches(*argv, "dsfield") == 0) { - NEXT_ARG(); - tkey->off = 1; - res = parse_cmd(&argc, &argv, 1, TU32,RU8,sel,tkey); - goto done; - } - if (strcmp(*argv, "ihl") == 0) { - NEXT_ARG(); - tkey->off = 0; - res = parse_cmd(&argc, &argv, 1, TU32,RU8,sel,tkey); - goto done; - } - if (strcmp(*argv, "protocol") == 0) { - NEXT_ARG(); - tkey->off = 9; - res = parse_cmd(&argc, &argv, 1, TU32,RU8,sel,tkey); - goto done; - } - /* jamal - fix this */ - if (matches(*argv, "precedence") == 0) { - NEXT_ARG(); - tkey->off = 1; - res = parse_cmd(&argc, &argv, 1, TU32,RU8,sel,tkey); - goto done; - } - /* jamal - validate this at some point */ - if (strcmp(*argv, "nofrag") == 0) { - NEXT_ARG(); - tkey->off = 6; - res = parse_cmd(&argc, &argv, 1, TU32,0x3F,sel,tkey); - goto done; - } - /* jamal - validate this at some point */ - if (strcmp(*argv, "firstfrag") == 0) { - NEXT_ARG(); - tkey->off = 6; - res = parse_cmd(&argc, &argv, 1, TU32,0x1F,sel,tkey); - goto done; - } - if (strcmp(*argv, "ce") == 0) { - NEXT_ARG(); - tkey->off = 6; - res = parse_cmd(&argc, &argv, 1, TU32,0x80,sel,tkey); - goto done; - } - if (strcmp(*argv, "df") == 0) { - NEXT_ARG(); - tkey->off = 6; - res = parse_cmd(&argc, &argv, 1, TU32,0x40,sel,tkey); - goto done; - } - if (strcmp(*argv, "mf") == 0) { - NEXT_ARG(); - tkey->off = 6; - res = parse_cmd(&argc, &argv, 1, TU32,0x20,sel,tkey); - goto done; - } - if (strcmp(*argv, "dport") == 0) { - NEXT_ARG(); - tkey->off = 22; - res = parse_cmd(&argc, &argv, 2, TU32,RU16,sel,tkey); - goto done; - } - if (strcmp(*argv, "sport") == 0) { - NEXT_ARG(); - tkey->off = 20; - res = parse_cmd(&argc, &argv, 2, TU32,RU16,sel,tkey); - goto done; - } - if (strcmp(*argv, "icmp_type") == 0) { - NEXT_ARG(); - tkey->off = 20; - res = parse_cmd(&argc, &argv, 1, TU32,RU8,sel,tkey); - goto done; - } - if (strcmp(*argv, "icmp_code") == 0) { - NEXT_ARG(); - tkey->off = 20; - res = parse_cmd(&argc, &argv, 1, TU32,RU8,sel,tkey); - goto done; - } - return -1; - - done: - *argc_p = argc; - *argv_p = argv; - return res; -} - -static int -parse_ip6(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - int res = -1; - return res; -} - -struct m_pedit_util p_pedit_ip = { - NULL, - "ip", - parse_ip, -}; - - -struct m_pedit_util p_pedit_ip6 = { - NULL, - "ip6", - parse_ip6, -}; diff --git a/tc/p_tcp.c b/tc/p_tcp.c deleted file mode 100644 index aab37a6..0000000 --- a/tc/p_tcp.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * m_pedit_tcp.c packet editor: TCP header - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim (hadi@cyberus.ca) - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include "utils.h" -#include "tc_util.h" -#include "m_pedit.h" - -static int -parse_tcp(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - int res = -1; - return res; -} -struct m_pedit_util p_pedit_tcp = { - NULL, - "tcp", - parse_tcp, -}; - - diff --git a/tc/p_udp.c b/tc/p_udp.c deleted file mode 100644 index 95ed993..0000000 --- a/tc/p_udp.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * m_pedit_udp.c packet editor: UDP header - * - * This program is free software; you can distribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim (hadi@cyberus.ca) - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include "utils.h" -#include "tc_util.h" -#include "m_pedit.h" - -static int -parse_udp(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) -{ - int res = -1; - return res; -} - -struct m_pedit_util p_pedit_udp = { - NULL, - "udp", - parse_udp, -}; - diff --git a/tc/q_atm.c b/tc/q_atm.c deleted file mode 100644 index 4c8dc0b..0000000 --- a/tc/q_atm.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * q_atm.c ATM. - * - * Hacked 1998-2000 by Werner Almesberger, EPFL ICA - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <ctype.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <atm.h> -#include <linux/atmdev.h> -#include <linux/atmarp.h> - -#include "utils.h" -#include "tc_util.h" - - -#define MAX_HDR_LEN 64 - -#define usage() return(-1) - - -static int atm_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - if (argc) { - fprintf(stderr,"Usage: atm\n"); - return -1; - } - return 0; -} - - -static void explain(void) -{ - fprintf(stderr, "Usage: ... atm ( pvc ADDR | svc ADDR [ sap SAP ] ) " - "[ qos QOS ] [ sndbuf BYTES ]\n"); - fprintf(stderr, " [ hdr HEX... ] [ excess ( CLASSID | clp ) ] " - "[ clip ]\n"); -} - - -static int atm_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, - struct nlmsghdr *n) -{ - struct sockaddr_atmsvc addr; - struct atm_qos qos; - struct atm_sap sap; - unsigned char hdr[MAX_HDR_LEN]; - __u32 excess = 0; - struct rtattr *tail; - int sndbuf = 0; - int hdr_len = -1; - int set_clip = 0; - int s; - - memset(&addr,0,sizeof(addr)); - (void) text2qos("aal5,ubr:sdu=9180,rx:none",&qos,0); - (void) text2sap("blli:l2=iso8802",&sap,0); - while (argc > 0) { - if (!strcmp(*argv,"pvc")) { - NEXT_ARG(); - if (text2atm(*argv,(struct sockaddr *) &addr, - sizeof(addr),T2A_PVC | T2A_NAME) < 0) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"svc")) { - NEXT_ARG(); - if (text2atm(*argv,(struct sockaddr *) &addr, - sizeof(addr),T2A_SVC | T2A_NAME) < 0) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"qos")) { - NEXT_ARG(); - if (text2qos(*argv,&qos,0) < 0) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"sndbuf")) { - char *end; - - NEXT_ARG(); - sndbuf = strtol(*argv,&end,0); - if (*end) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"sap")) { - NEXT_ARG(); - if (addr.sas_family != AF_ATMSVC || - text2sap(*argv,&sap,T2A_NAME) < 0) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"hdr")) { - unsigned char *ptr; - char *walk; - - NEXT_ARG(); - ptr = hdr; - for (walk = *argv; *walk; walk++) { - int tmp; - - if (ptr == hdr+MAX_HDR_LEN) { - fprintf(stderr,"header is too long\n"); - return -1; - } - if (*walk == '.') continue; - if (!isxdigit(walk[0]) || !walk[1] || - !isxdigit(walk[1])) { - explain(); - return -1; - } - sscanf(walk,"%2x",&tmp); - *ptr++ = tmp; - walk++; - } - hdr_len = ptr-hdr; - } - else if (!strcmp(*argv,"excess")) { - NEXT_ARG(); - if (!strcmp(*argv,"clp")) excess = 0; - else if (get_tc_classid(&excess,*argv)) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"clip")) { - set_clip = 1; - } - else { - explain(); - return 1; - } - argc--; - argv++; - } - s = socket(addr.sas_family,SOCK_DGRAM,0); - if (s < 0) { - perror("socket"); - return -1; - } - if (setsockopt(s,SOL_ATM,SO_ATMQOS,&qos,sizeof(qos)) < 0) { - perror("SO_ATMQOS"); - return -1; - } - if (sndbuf) - if (setsockopt(s,SOL_SOCKET,SO_SNDBUF,&sndbuf,sizeof(sndbuf)) < 0) { - perror("SO_SNDBUF"); - return -1; - } - if (addr.sas_family == AF_ATMSVC && setsockopt(s,SOL_ATM,SO_ATMSAP, - &sap,sizeof(sap)) < 0) { - perror("SO_ATMSAP"); - return -1; - } - if (connect(s,(struct sockaddr *) &addr,addr.sas_family == AF_ATMPVC ? - sizeof(struct sockaddr_atmpvc) : sizeof(addr)) < 0) { - perror("connect"); - return -1; - } - if (set_clip) - if (ioctl(s,ATMARP_MKIP,0) < 0) { - perror("ioctl ATMARP_MKIP"); - return -1; - } - tail = NLMSG_TAIL(n); - addattr_l(n,1024,TCA_OPTIONS,NULL,0); - addattr_l(n,1024,TCA_ATM_FD,&s,sizeof(s)); - if (excess) addattr_l(n,1024,TCA_ATM_EXCESS,&excess,sizeof(excess)); - if (hdr_len != -1) addattr_l(n,1024,TCA_ATM_HDR,hdr,hdr_len); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - - - -static int atm_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct rtattr *tb[TCA_ATM_MAX+1]; - char buffer[MAX_ATM_ADDR_LEN+1]; - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_ATM_MAX, opt); - if (tb[TCA_ATM_ADDR]) { - if (RTA_PAYLOAD(tb[TCA_ATM_ADDR]) < - sizeof(struct sockaddr_atmpvc)) - fprintf(stderr,"ATM: address too short\n"); - else { - if (atm2text(buffer,MAX_ATM_ADDR_LEN, - RTA_DATA(tb[TCA_ATM_ADDR]),A2T_PRETTY | A2T_NAME) < - 0) fprintf(stderr,"atm2text error\n"); - fprintf(f,"pvc %s ",buffer); - } - } - if (tb[TCA_ATM_HDR]) { - int i; - - fprintf(f,"hdr"); - for (i = 0; i < RTA_PAYLOAD(tb[TCA_ATM_HDR]); i++) - fprintf(f,"%c%02x",i ? '.' : ' ', - ((unsigned char *) RTA_DATA(tb[TCA_ATM_HDR]))[i]); - if (!i) fprintf(f," ."); - fprintf(f," "); - } - if (tb[TCA_ATM_EXCESS]) { - __u32 excess; - - if (RTA_PAYLOAD(tb[TCA_ATM_EXCESS]) < sizeof(excess)) - fprintf(stderr,"ATM: excess class ID too short\n"); - else { - excess = *(__u32 *) RTA_DATA(tb[TCA_ATM_EXCESS]); - if (!excess) fprintf(f,"excess clp "); - else { - char buf[64]; - - print_tc_classid(buf,sizeof(buf),excess); - fprintf(f,"excess %s ",buf); - } - } - } - if (tb[TCA_ATM_STATE]) { - static const char *map[] = { ATM_VS2TXT_MAP }; - int state; - - if (RTA_PAYLOAD(tb[TCA_ATM_STATE]) < sizeof(state)) - fprintf(stderr,"ATM: state field too short\n"); - else { - state = *(int *) RTA_DATA(tb[TCA_ATM_STATE]); - fprintf(f,"%s ",map[state]); - } - } - return 0; -} - - -struct qdisc_util atm_qdisc_util = { - .id = "atm", - .parse_qopt = atm_parse_opt, - .print_qopt = atm_print_opt, - .parse_copt = atm_parse_class_opt, - .print_copt = atm_print_opt, -}; diff --git a/tc/q_cbq.c b/tc/q_cbq.c deleted file mode 100644 index a456eda..0000000 --- a/tc/q_cbq.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * q_cbq.c CBQ. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" -#include "tc_cbq.h" - -static void explain_class(void) -{ - fprintf(stderr, "Usage: ... cbq bandwidth BPS rate BPS maxburst PKTS [ avpkt BYTES ]\n"); - fprintf(stderr, " [ minburst PKTS ] [ bounded ] [ isolated ]\n"); - fprintf(stderr, " [ allot BYTES ] [ mpu BYTES ] [ weight RATE ]\n"); - fprintf(stderr, " [ prio NUMBER ] [ cell BYTES ] [ ewma LOG ]\n"); - fprintf(stderr, " [ estimator INTERVAL TIME_CONSTANT ]\n"); - fprintf(stderr, " [ split CLASSID ] [ defmap MASK/CHANGE ]\n"); -} - -static void explain(void) -{ - fprintf(stderr, "Usage: ... cbq bandwidth BPS avpkt BYTES [ mpu BYTES ]\n"); - fprintf(stderr, " [ cell BYTES ] [ ewma LOG ]\n"); -} - -static void explain1(char *arg) -{ - fprintf(stderr, "Illegal \"%s\"\n", arg); -} - -#define usage() return(-1) - -static int cbq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - struct tc_ratespec r; - struct tc_cbq_lssopt lss; - __u32 rtab[256]; - unsigned mpu=0, avpkt=0, allot=0; - int cell_log=-1; - int ewma_log=-1; - struct rtattr *tail; - - memset(&lss, 0, sizeof(lss)); - memset(&r, 0, sizeof(r)); - - while (argc > 0) { - if (strcmp(*argv, "bandwidth") == 0 || - strcmp(*argv, "rate") == 0) { - NEXT_ARG(); - if (get_rate(&r.rate, *argv)) { - explain1("bandwidth"); - return -1; - } - } else if (strcmp(*argv, "ewma") == 0) { - NEXT_ARG(); - if (get_integer(&ewma_log, *argv, 0)) { - explain1("ewma"); - return -1; - } - if (ewma_log > 31) { - fprintf(stderr, "ewma_log must be < 32\n"); - return -1; - } - } else if (strcmp(*argv, "cell") == 0) { - unsigned cell; - int i; - NEXT_ARG(); - if (get_size(&cell, *argv)) { - explain1("cell"); - return -1; - } - for (i=0; i<32; i++) - if ((1<<i) == cell) - break; - if (i>=32) { - fprintf(stderr, "cell must be 2^n\n"); - return -1; - } - cell_log = i; - } else if (strcmp(*argv, "avpkt") == 0) { - NEXT_ARG(); - if (get_size(&avpkt, *argv)) { - explain1("avpkt"); - return -1; - } - } else if (strcmp(*argv, "mpu") == 0) { - NEXT_ARG(); - if (get_size(&mpu, *argv)) { - explain1("mpu"); - return -1; - } - } else if (strcmp(*argv, "allot") == 0) { - NEXT_ARG(); - /* Accept and ignore "allot" for backward compatibility */ - if (get_size(&allot, *argv)) { - explain1("allot"); - return -1; - } - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - - /* OK. All options are parsed. */ - - if (r.rate == 0) { - fprintf(stderr, "CBQ: bandwidth is required parameter.\n"); - return -1; - } - if (avpkt == 0) { - fprintf(stderr, "CBQ: \"avpkt\" is required.\n"); - return -1; - } - if (allot < (avpkt*3)/2) - allot = (avpkt*3)/2; - - if ((cell_log = tc_calc_rtable(r.rate, rtab, cell_log, allot, mpu)) < 0) { - fprintf(stderr, "CBQ: failed to calculate rate table.\n"); - return -1; - } - r.cell_log = cell_log; - r.mpu = mpu; - - if (ewma_log < 0) - ewma_log = TC_CBQ_DEF_EWMA; - lss.ewma_log = ewma_log; - lss.maxidle = tc_cbq_calc_maxidle(r.rate, r.rate, avpkt, lss.ewma_log, 0); - lss.change = TCF_CBQ_LSS_MAXIDLE|TCF_CBQ_LSS_EWMA|TCF_CBQ_LSS_AVPKT; - lss.avpkt = avpkt; - - tail = NLMSG_TAIL(n); - addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); - addattr_l(n, 1024, TCA_CBQ_RATE, &r, sizeof(r)); - addattr_l(n, 1024, TCA_CBQ_LSSOPT, &lss, sizeof(lss)); - addattr_l(n, 3024, TCA_CBQ_RTAB, rtab, 1024); - if (show_raw) { - int i; - for (i=0; i<256; i++) - printf("%u ", rtab[i]); - printf("\n"); - } - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - -static int cbq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - int wrr_ok=0, fopt_ok=0; - struct tc_ratespec r; - struct tc_cbq_lssopt lss; - struct tc_cbq_wrropt wrr; - struct tc_cbq_fopt fopt; - struct tc_cbq_ovl ovl; - __u32 rtab[256]; - unsigned mpu=0; - int cell_log=-1; - int ewma_log=-1; - unsigned bndw = 0; - unsigned minburst=0, maxburst=0; - struct rtattr *tail; - - memset(&r, 0, sizeof(r)); - memset(&lss, 0, sizeof(lss)); - memset(&wrr, 0, sizeof(wrr)); - memset(&fopt, 0, sizeof(fopt)); - memset(&ovl, 0, sizeof(ovl)); - - while (argc > 0) { - if (strcmp(*argv, "rate") == 0) { - NEXT_ARG(); - if (get_rate(&r.rate, *argv)) { - explain1("rate"); - return -1; - } - } else if (strcmp(*argv, "bandwidth") == 0) { - NEXT_ARG(); - if (get_rate(&bndw, *argv)) { - explain1("bandwidth"); - return -1; - } - } else if (strcmp(*argv, "minidle") == 0) { - NEXT_ARG(); - if (get_u32(&lss.minidle, *argv, 0)) { - explain1("minidle"); - return -1; - } - lss.change |= TCF_CBQ_LSS_MINIDLE; - } else if (strcmp(*argv, "minburst") == 0) { - NEXT_ARG(); - if (get_u32(&minburst, *argv, 0)) { - explain1("minburst"); - return -1; - } - lss.change |= TCF_CBQ_LSS_OFFTIME; - } else if (strcmp(*argv, "maxburst") == 0) { - NEXT_ARG(); - if (get_u32(&maxburst, *argv, 0)) { - explain1("maxburst"); - return -1; - } - lss.change |= TCF_CBQ_LSS_MAXIDLE; - } else if (strcmp(*argv, "bounded") == 0) { - lss.flags |= TCF_CBQ_LSS_BOUNDED; - lss.change |= TCF_CBQ_LSS_FLAGS; - } else if (strcmp(*argv, "borrow") == 0) { - lss.flags &= ~TCF_CBQ_LSS_BOUNDED; - lss.change |= TCF_CBQ_LSS_FLAGS; - } else if (strcmp(*argv, "isolated") == 0) { - lss.flags |= TCF_CBQ_LSS_ISOLATED; - lss.change |= TCF_CBQ_LSS_FLAGS; - } else if (strcmp(*argv, "sharing") == 0) { - lss.flags &= ~TCF_CBQ_LSS_ISOLATED; - lss.change |= TCF_CBQ_LSS_FLAGS; - } else if (strcmp(*argv, "ewma") == 0) { - NEXT_ARG(); - if (get_integer(&ewma_log, *argv, 0)) { - explain1("ewma"); - return -1; - } - if (ewma_log > 31) { - fprintf(stderr, "ewma_log must be < 32\n"); - return -1; - } - lss.change |= TCF_CBQ_LSS_EWMA; - } else if (strcmp(*argv, "cell") == 0) { - unsigned cell; - int i; - NEXT_ARG(); - if (get_size(&cell, *argv)) { - explain1("cell"); - return -1; - } - for (i=0; i<32; i++) - if ((1<<i) == cell) - break; - if (i>=32) { - fprintf(stderr, "cell must be 2^n\n"); - return -1; - } - cell_log = i; - } else if (strcmp(*argv, "prio") == 0) { - unsigned prio; - NEXT_ARG(); - if (get_u32(&prio, *argv, 0)) { - explain1("prio"); - return -1; - } - if (prio > TC_CBQ_MAXPRIO) { - fprintf(stderr, "\"prio\" must be number in the range 1...%d\n", TC_CBQ_MAXPRIO); - return -1; - } - wrr.priority = prio; - wrr_ok++; - } else if (strcmp(*argv, "allot") == 0) { - NEXT_ARG(); - if (get_size(&wrr.allot, *argv)) { - explain1("allot"); - return -1; - } - } else if (strcmp(*argv, "avpkt") == 0) { - NEXT_ARG(); - if (get_size(&lss.avpkt, *argv)) { - explain1("avpkt"); - return -1; - } - lss.change |= TCF_CBQ_LSS_AVPKT; - } else if (strcmp(*argv, "mpu") == 0) { - NEXT_ARG(); - if (get_size(&mpu, *argv)) { - explain1("mpu"); - return -1; - } - } else if (strcmp(*argv, "weight") == 0) { - NEXT_ARG(); - if (get_size(&wrr.weight, *argv)) { - explain1("weight"); - return -1; - } - wrr_ok++; - } else if (strcmp(*argv, "split") == 0) { - NEXT_ARG(); - if (get_tc_classid(&fopt.split, *argv)) { - fprintf(stderr, "Invalid split node ID.\n"); - usage(); - } - fopt_ok++; - } else if (strcmp(*argv, "defmap") == 0) { - int err; - NEXT_ARG(); - err = sscanf(*argv, "%08x/%08x", &fopt.defmap, &fopt.defchange); - if (err < 1) { - fprintf(stderr, "Invalid defmap, should be MASK32[/MASK]\n"); - return -1; - } - if (err == 1) - fopt.defchange = ~0; - fopt_ok++; - } else if (strcmp(*argv, "help") == 0) { - explain_class(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain_class(); - return -1; - } - argc--; argv++; - } - - /* OK. All options are parsed. */ - - /* 1. Prepare link sharing scheduler parameters */ - if (r.rate) { - unsigned pktsize = wrr.allot; - if (wrr.allot < (lss.avpkt*3)/2) - wrr.allot = (lss.avpkt*3)/2; - if ((cell_log = tc_calc_rtable(r.rate, rtab, cell_log, pktsize, mpu)) < 0) { - fprintf(stderr, "CBQ: failed to calculate rate table.\n"); - return -1; - } - r.cell_log = cell_log; - r.mpu = mpu; - } - if (ewma_log < 0) - ewma_log = TC_CBQ_DEF_EWMA; - lss.ewma_log = ewma_log; - if (lss.change&(TCF_CBQ_LSS_OFFTIME|TCF_CBQ_LSS_MAXIDLE)) { - if (lss.avpkt == 0) { - fprintf(stderr, "CBQ: avpkt is required for max/minburst.\n"); - return -1; - } - if (bndw==0 || r.rate == 0) { - fprintf(stderr, "CBQ: bandwidth&rate are required for max/minburst.\n"); - return -1; - } - } - if (wrr.priority == 0 && (n->nlmsg_flags&NLM_F_EXCL)) { - wrr_ok = 1; - wrr.priority = TC_CBQ_MAXPRIO; - if (wrr.allot == 0) - wrr.allot = (lss.avpkt*3)/2; - } - if (wrr_ok) { - if (wrr.weight == 0) - wrr.weight = (wrr.priority == TC_CBQ_MAXPRIO) ? 1 : r.rate; - if (wrr.allot == 0) { - fprintf(stderr, "CBQ: \"allot\" is required to set WRR parameters.\n"); - return -1; - } - } - if (lss.change&TCF_CBQ_LSS_MAXIDLE) { - lss.maxidle = tc_cbq_calc_maxidle(bndw, r.rate, lss.avpkt, ewma_log, maxburst); - lss.change |= TCF_CBQ_LSS_MAXIDLE; - lss.change |= TCF_CBQ_LSS_EWMA|TCF_CBQ_LSS_AVPKT; - } - if (lss.change&TCF_CBQ_LSS_OFFTIME) { - lss.offtime = tc_cbq_calc_offtime(bndw, r.rate, lss.avpkt, ewma_log, minburst); - lss.change |= TCF_CBQ_LSS_OFFTIME; - lss.change |= TCF_CBQ_LSS_EWMA|TCF_CBQ_LSS_AVPKT; - } - if (lss.change&TCF_CBQ_LSS_MINIDLE) { - lss.minidle <<= lss.ewma_log; - lss.change |= TCF_CBQ_LSS_EWMA; - } - - tail = NLMSG_TAIL(n); - addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); - if (lss.change) { - lss.change |= TCF_CBQ_LSS_FLAGS; - addattr_l(n, 1024, TCA_CBQ_LSSOPT, &lss, sizeof(lss)); - } - if (wrr_ok) - addattr_l(n, 1024, TCA_CBQ_WRROPT, &wrr, sizeof(wrr)); - if (fopt_ok) - addattr_l(n, 1024, TCA_CBQ_FOPT, &fopt, sizeof(fopt)); - if (r.rate) { - addattr_l(n, 1024, TCA_CBQ_RATE, &r, sizeof(r)); - addattr_l(n, 3024, TCA_CBQ_RTAB, rtab, 1024); - if (show_raw) { - int i; - for (i=0; i<256; i++) - printf("%u ", rtab[i]); - printf("\n"); - } - } - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - - -static int cbq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct rtattr *tb[TCA_CBQ_MAX+1]; - struct tc_ratespec *r = NULL; - struct tc_cbq_lssopt *lss = NULL; - struct tc_cbq_wrropt *wrr = NULL; - struct tc_cbq_fopt *fopt = NULL; - struct tc_cbq_ovl *ovl = NULL; - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_CBQ_MAX, opt); - - if (tb[TCA_CBQ_RATE]) { - if (RTA_PAYLOAD(tb[TCA_CBQ_RATE]) < sizeof(*r)) - fprintf(stderr, "CBQ: too short rate opt\n"); - else - r = RTA_DATA(tb[TCA_CBQ_RATE]); - } - if (tb[TCA_CBQ_LSSOPT]) { - if (RTA_PAYLOAD(tb[TCA_CBQ_LSSOPT]) < sizeof(*lss)) - fprintf(stderr, "CBQ: too short lss opt\n"); - else - lss = RTA_DATA(tb[TCA_CBQ_LSSOPT]); - } - if (tb[TCA_CBQ_WRROPT]) { - if (RTA_PAYLOAD(tb[TCA_CBQ_WRROPT]) < sizeof(*wrr)) - fprintf(stderr, "CBQ: too short wrr opt\n"); - else - wrr = RTA_DATA(tb[TCA_CBQ_WRROPT]); - } - if (tb[TCA_CBQ_FOPT]) { - if (RTA_PAYLOAD(tb[TCA_CBQ_FOPT]) < sizeof(*fopt)) - fprintf(stderr, "CBQ: too short fopt\n"); - else - fopt = RTA_DATA(tb[TCA_CBQ_FOPT]); - } - if (tb[TCA_CBQ_OVL_STRATEGY]) { - if (RTA_PAYLOAD(tb[TCA_CBQ_OVL_STRATEGY]) < sizeof(*ovl)) - fprintf(stderr, "CBQ: too short overlimit strategy %u/%u\n", - (unsigned) RTA_PAYLOAD(tb[TCA_CBQ_OVL_STRATEGY]), - (unsigned) sizeof(*ovl)); - else - ovl = RTA_DATA(tb[TCA_CBQ_OVL_STRATEGY]); - } - - if (r) { - char buf[64]; - print_rate(buf, sizeof(buf), r->rate); - fprintf(f, "rate %s ", buf); - if (show_details) { - fprintf(f, "cell %ub ", 1<<r->cell_log); - if (r->mpu) - fprintf(f, "mpu %ub ", r->mpu); - } - } - if (lss && lss->flags) { - int comma=0; - fprintf(f, "("); - if (lss->flags&TCF_CBQ_LSS_BOUNDED) { - fprintf(f, "bounded"); - comma=1; - } - if (lss->flags&TCF_CBQ_LSS_ISOLATED) { - if (comma) - fprintf(f, ","); - fprintf(f, "isolated"); - } - fprintf(f, ") "); - } - if (wrr) { - if (wrr->priority != TC_CBQ_MAXPRIO) - fprintf(f, "prio %u", wrr->priority); - else - fprintf(f, "prio no-transmit"); - if (show_details) { - char buf[64]; - fprintf(f, "/%u ", wrr->cpriority); - if (wrr->weight != 1) { - print_rate(buf, sizeof(buf), wrr->weight); - fprintf(f, "weight %s ", buf); - } - if (wrr->allot) - fprintf(f, "allot %ub ", wrr->allot); - } - } - if (lss && show_details) { - fprintf(f, "\nlevel %u ewma %u avpkt %ub ", lss->level, lss->ewma_log, lss->avpkt); - if (lss->maxidle) { - fprintf(f, "maxidle %luus ", tc_core_tick2usec(lss->maxidle>>lss->ewma_log)); - if (show_raw) - fprintf(f, "[%08x] ", lss->maxidle); - } - if (lss->minidle!=0x7fffffff) { - fprintf(f, "minidle %luus ", tc_core_tick2usec(lss->minidle>>lss->ewma_log)); - if (show_raw) - fprintf(f, "[%08x] ", lss->minidle); - } - if (lss->offtime) { - fprintf(f, "offtime %luus ", tc_core_tick2usec(lss->offtime)); - if (show_raw) - fprintf(f, "[%08x] ", lss->offtime); - } - } - if (fopt && show_details) { - char buf[64]; - print_tc_classid(buf, sizeof(buf), fopt->split); - fprintf(f, "\nsplit %s ", buf); - if (fopt->defmap) { - fprintf(f, "defmap %08x", fopt->defmap); - } - } - return 0; -} - -static int cbq_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) -{ - struct tc_cbq_xstats *st; - - if (xstats == NULL) - return 0; - - if (RTA_PAYLOAD(xstats) < sizeof(*st)) - return -1; - - st = RTA_DATA(xstats); - fprintf(f, " borrowed %u overactions %u avgidle %g undertime %g", st->borrows, - st->overactions, (double)st->avgidle, (double)st->undertime); - return 0; -} - -struct qdisc_util cbq_qdisc_util = { - .id = "cbq", - .parse_qopt = cbq_parse_opt, - .print_qopt = cbq_print_opt, - .print_xstats = cbq_print_xstats, - .parse_copt = cbq_parse_class_opt, - .print_copt = cbq_print_opt, -}; - diff --git a/tc/q_dsmark.c b/tc/q_dsmark.c deleted file mode 100644 index cdb5bf2..0000000 --- a/tc/q_dsmark.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * q_dsmark.c Differentiated Services field marking. - * - * Hacked 1998,1999 by Werner Almesberger, EPFL ICA - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - - -#define usage() return(-1) - - -static void explain(void) -{ - fprintf(stderr,"Usage: dsmark indices INDICES [ default_index " - "DEFAULT_INDEX ] [ set_tc_index ]\n"); -} - - -static int dsmark_parse_opt(struct qdisc_util *qu, int argc, char **argv, - struct nlmsghdr *n) -{ - struct rtattr *tail; - __u16 ind; - char *end; - int dflt,set_tc_index; - - ind = set_tc_index = 0; - dflt = -1; - while (argc > 0) { - if (!strcmp(*argv,"indices")) { - NEXT_ARG(); - ind = strtoul(*argv,&end,0); - if (*end) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"default_index") || !strcmp(*argv, - "default")) { - NEXT_ARG(); - dflt = strtoul(*argv,&end,0); - if (*end) { - explain(); - return -1; - } - } - else if (!strcmp(*argv,"set_tc_index")) { - set_tc_index = 1; - } - else { - explain(); - return -1; - } - argc--; - argv++; - } - if (!ind) { - explain(); - return -1; - } - tail = NLMSG_TAIL(n); - addattr_l(n,1024,TCA_OPTIONS,NULL,0); - addattr_l(n,1024,TCA_DSMARK_INDICES,&ind,sizeof(ind)); - if (dflt != -1) { - __u16 tmp = dflt; - - addattr_l(n,1024,TCA_DSMARK_DEFAULT_INDEX,&tmp,sizeof(tmp)); - } - if (set_tc_index) addattr_l(n,1024,TCA_DSMARK_SET_TC_INDEX,NULL,0); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - - -static void explain_class(void) -{ - fprintf(stderr, "Usage: ... dsmark [ mask MASK ] [ value VALUE ]\n"); -} - - -static int dsmark_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, - struct nlmsghdr *n) -{ - struct rtattr *tail; - __u8 tmp; - char *end; - - tail = NLMSG_TAIL(n); - addattr_l(n,1024,TCA_OPTIONS,NULL,0); - while (argc > 0) { - if (!strcmp(*argv,"mask")) { - NEXT_ARG(); - tmp = strtoul(*argv,&end,0); - if (*end) { - explain_class(); - return -1; - } - addattr_l(n,1024,TCA_DSMARK_MASK,&tmp,1); - } - else if (!strcmp(*argv,"value")) { - NEXT_ARG(); - tmp = strtoul(*argv,&end,0); - if (*end) { - explain_class(); - return -1; - } - addattr_l(n,1024,TCA_DSMARK_VALUE,&tmp,1); - } - else { - explain_class(); - return -1; - } - argc--; - argv++; - } - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - - - -static int dsmark_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct rtattr *tb[TCA_DSMARK_MAX+1]; - - if (!opt) return 0; - memset(tb, 0, sizeof(tb)); - parse_rtattr(tb, TCA_DSMARK_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)); - if (tb[TCA_DSMARK_MASK]) { - if (!RTA_PAYLOAD(tb[TCA_DSMARK_MASK])) - fprintf(stderr,"dsmark: empty mask\n"); - else fprintf(f,"mask 0x%02x ", - *(__u8 *) RTA_DATA(tb[TCA_DSMARK_MASK])); - } - if (tb[TCA_DSMARK_VALUE]) { - if (!RTA_PAYLOAD(tb[TCA_DSMARK_VALUE])) - fprintf(stderr,"dsmark: empty value\n"); - else fprintf(f,"value 0x%02x ", - *(__u8 *) RTA_DATA(tb[TCA_DSMARK_VALUE])); - } - if (tb[TCA_DSMARK_INDICES]) { - if (RTA_PAYLOAD(tb[TCA_DSMARK_INDICES]) < sizeof(__u16)) - fprintf(stderr,"dsmark: indices too short\n"); - else fprintf(f,"indices 0x%04x ", - *(__u16 *) RTA_DATA(tb[TCA_DSMARK_INDICES])); - } - if (tb[TCA_DSMARK_DEFAULT_INDEX]) { - if (RTA_PAYLOAD(tb[TCA_DSMARK_DEFAULT_INDEX]) < sizeof(__u16)) - fprintf(stderr,"dsmark: default_index too short\n"); - else fprintf(f,"default_index 0x%04x ", - *(__u16 *) RTA_DATA(tb[TCA_DSMARK_DEFAULT_INDEX])); - } - if (tb[TCA_DSMARK_SET_TC_INDEX]) fprintf(f,"set_tc_index "); - return 0; -} - - -struct qdisc_util dsmark_qdisc_util = { - .id = "dsmark", - .parse_qopt = dsmark_parse_opt, - .print_qopt = dsmark_print_opt, - .parse_copt = dsmark_parse_class_opt, - .print_copt = dsmark_print_opt, -}; diff --git a/tc/q_fifo.c b/tc/q_fifo.c deleted file mode 100644 index 9f3b3eb..0000000 --- a/tc/q_fifo.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * q_fifo.c FIFO. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - -static void explain(void) -{ - fprintf(stderr, "Usage: ... [p|b]fifo [ limit NUMBER ]\n"); -} - -#define usage() return(-1) - -static int fifo_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - int ok=0; - struct tc_fifo_qopt opt; - memset(&opt, 0, sizeof(opt)); - - while (argc > 0) { - if (strcmp(*argv, "limit") == 0) { - NEXT_ARG(); - if (get_size(&opt.limit, *argv)) { - fprintf(stderr, "Illegal \"limit\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - - if (ok) - addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt)); - return 0; -} - -static int fifo_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct tc_fifo_qopt *qopt; - - if (opt == NULL) - return 0; - - if (RTA_PAYLOAD(opt) < sizeof(*qopt)) - return -1; - qopt = RTA_DATA(opt); - if (strcmp(qu->id, "bfifo") == 0) { - SPRINT_BUF(b1); - fprintf(f, "limit %s", sprint_size(qopt->limit, b1)); - } else - fprintf(f, "limit %up", qopt->limit); - return 0; -} - - -struct qdisc_util bfifo_qdisc_util = { - .id = "bfifo", - .parse_qopt = fifo_parse_opt, - .print_qopt = fifo_print_opt, -}; - -struct qdisc_util pfifo_qdisc_util = { - .id = "pfifo", - .parse_qopt = fifo_parse_opt, - .print_qopt = fifo_print_opt, -}; - -extern int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt); -struct qdisc_util pfifo_fast_qdisc_util = { - .id = "pfifo_fast", - .print_qopt = prio_print_opt, -}; diff --git a/tc/q_gred.c b/tc/q_gred.c deleted file mode 100644 index 0526c75..0000000 --- a/tc/q_gred.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * q_gred.c GRED. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim(hadi@nortelnetworks.com) - * code ruthlessly ripped from - * Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - -#include "tc_red.h" - - -#if 0 -#define DPRINTF(format,args...) fprintf(stderr,format,##args) -#else -#define DPRINTF(format,args...) -#endif - -static void explain(void) -{ - fprintf(stderr, "Usage: ... gred DP drop-probability limit BYTES " - "min BYTES max BYTES\n"); - fprintf(stderr, " avpkt BYTES burst PACKETS probability PROBABILITY " - "bandwidth KBPS\n"); - fprintf(stderr, " [prio value]\n"); - fprintf(stderr," OR ...\n"); - fprintf(stderr," gred setup DPs <num of DPs> default <default DP> " - "[grio]\n"); -} - -#define usage() return(-1) - -static int init_gred(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - - struct rtattr *tail; - struct tc_gred_sopt opt; - memset(&opt, 0, sizeof(struct tc_gred_sopt)); - - while (argc > 0) { - DPRINTF(stderr,"init_gred: invoked with %s\n",*argv); - if (strcmp(*argv, "DPs") == 0) { - NEXT_ARG(); - DPRINTF(stderr,"init_gred: next_arg with %s\n",*argv); - opt.DPs=strtol(*argv, (char **)NULL, 10); - if (opt.DPs >MAX_DPs) { /* need a better error check */ - fprintf(stderr, "DPs =%u \n",opt.DPs); - fprintf(stderr, "Illegal \"DPs\"\n"); - fprintf(stderr, "GRED: only %d DPs are " - "currently supported\n",MAX_DPs); - return -1; - } - } else if (strcmp(*argv, "default") == 0) { - NEXT_ARG(); - opt.def_DP=strtol(*argv, (char **)NULL, 10); - if (!opt.DPs) { - fprintf(stderr, "\"default DP\" must be " - "defined after DPs\n"); - return -1; - } - if (opt.def_DP>opt.DPs) { -/* - fprintf(stderr, "\"default DP\" must be less than %d\nNote: DP runs from 0 to %d for %d DPs\n",opt.DPs,opt.DPs-1,opt.DPs); -*/ - fprintf(stderr, "\"default DP\" must be less than %d\n",opt.DPs); - return -1; - } - } else if (strcmp(*argv, "grio") == 0) { - opt.grio=1; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; -} - -if ((!opt.DPs) || (!opt.def_DP)) -{ - fprintf(stderr, "Illegal gred setup parameters \n"); - return -1; -} -DPRINTF("TC_GRED: sending DPs=%d default=%d\n",opt.DPs,opt.def_DP); - n->nlmsg_flags|=NLM_F_CREATE; - tail = NLMSG_TAIL(n); - addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); - addattr_l(n, 1024, TCA_GRED_DPS, &opt, sizeof(struct tc_gred_sopt)); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; -return 0; -} -/* -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -*/ -static int gred_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - int ok=0; - struct tc_gred_qopt opt; - unsigned burst = 0; - unsigned avpkt = 0; - double probability = 0.02; - unsigned rate = 0; - int wlog; - __u8 sbuf[256]; - struct rtattr *tail; - - memset(&opt, 0, sizeof(opt)); - - while (argc > 0) { - if (strcmp(*argv, "limit") == 0) { - NEXT_ARG(); - if (get_size(&opt.limit, *argv)) { - fprintf(stderr, "Illegal \"limit\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "setup") == 0) { - if (ok) { - fprintf(stderr, "Illegal \"setup\"\n"); - return -1; - } - return init_gred(qu,argc-1, argv+1,n); - - } else if (strcmp(*argv, "min") == 0) { - NEXT_ARG(); - if (get_size(&opt.qth_min, *argv)) { - fprintf(stderr, "Illegal \"min\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "max") == 0) { - NEXT_ARG(); - if (get_size(&opt.qth_max, *argv)) { - fprintf(stderr, "Illegal \"max\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "DP") == 0) { - NEXT_ARG(); - opt.DP=strtol(*argv, (char **)NULL, 10); - DPRINTF ("\n ******* DP =%u\n",opt.DP); - if (opt.DP >MAX_DPs) { /* need a better error check */ - fprintf(stderr, "DP =%u \n",opt.DP); - fprintf(stderr, "Illegal \"DP\"\n"); - fprintf(stderr, "GRED: only %d DPs are currently supported\n",MAX_DPs); - return -1; - } - ok++; - } else if (strcmp(*argv, "burst") == 0) { - NEXT_ARG(); - if (get_unsigned(&burst, *argv, 0)) { - fprintf(stderr, "Illegal \"burst\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "avpkt") == 0) { - NEXT_ARG(); - if (get_size(&avpkt, *argv)) { - fprintf(stderr, "Illegal \"avpkt\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "probability") == 0) { - NEXT_ARG(); - if (sscanf(*argv, "%lg", &probability) != 1) { - fprintf(stderr, "Illegal \"probability\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "prio") == 0) { - NEXT_ARG(); - opt.prio=strtol(*argv, (char **)NULL, 10); - /* some error check here */ - ok++; - } else if (strcmp(*argv, "bandwidth") == 0) { - NEXT_ARG(); - if (get_rate(&rate, *argv)) { - fprintf(stderr, "Illegal \"bandwidth\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - - if (!ok) - return 0; - - if (rate == 0) - get_rate(&rate, "10Mbit"); - - if (!opt.qth_min || !opt.qth_max || !burst || !opt.limit || !avpkt || - (opt.DP<0)) { - fprintf(stderr, "Required parameter (min, max, burst, limit, " - "avpket, DP) is missing\n"); - return -1; - } - - if ((wlog = tc_red_eval_ewma(opt.qth_min, burst, avpkt)) < 0) { - fprintf(stderr, "GRED: failed to calculate EWMA constant.\n"); - return -1; - } - if (wlog >= 10) - fprintf(stderr, "GRED: WARNING. Burst %d seems to be to " - "large.\n", burst); - opt.Wlog = wlog; - if ((wlog = tc_red_eval_P(opt.qth_min, opt.qth_max, probability)) < 0) { - fprintf(stderr, "GRED: failed to calculate probability.\n"); - return -1; - } - opt.Plog = wlog; - if ((wlog = tc_red_eval_idle_damping(opt.Wlog, avpkt, rate, sbuf)) < 0) - { - fprintf(stderr, "GRED: failed to calculate idle damping " - "table.\n"); - return -1; - } - opt.Scell_log = wlog; - - tail = NLMSG_TAIL(n); - addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); - addattr_l(n, 1024, TCA_GRED_PARMS, &opt, sizeof(opt)); - addattr_l(n, 1024, TCA_GRED_STAB, sbuf, 256); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - -static int gred_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct rtattr *tb[TCA_GRED_STAB+1]; - struct tc_gred_qopt *qopt; - int i; - SPRINT_BUF(b1); - SPRINT_BUF(b2); - SPRINT_BUF(b3); - SPRINT_BUF(b4); - SPRINT_BUF(b5); - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_GRED_STAB, opt); - - if (tb[TCA_GRED_PARMS] == NULL) - return -1; - - qopt = RTA_DATA(tb[TCA_GRED_PARMS]); - if (RTA_PAYLOAD(tb[TCA_GRED_PARMS]) < sizeof(*qopt)*MAX_DPs) { - fprintf(f,"\n GRED received message smaller than expected\n"); - return -1; - } - -/* Bad hack! should really return a proper message as shown above*/ - - for (i=0;i<MAX_DPs;i++, qopt++) { - if (qopt->DP >= MAX_DPs) continue; - fprintf(f, "\n DP:%d (prio %d) Average Queue %s Measured " - "Queue %s ", - qopt->DP, - qopt->prio, - sprint_size(qopt->qave, b4), - sprint_size(qopt->backlog, b5)); - fprintf(f, "\n\t Packet drops: %d (forced %d early %d) ", - qopt->forced+qopt->early, - qopt->forced, - qopt->early); - fprintf(f, "\n\t Packet totals: %u (bytes %u) ", - qopt->packets, - qopt->bytesin); - if (show_details) - fprintf(f, "\n limit %s min %s max %s ", - sprint_size(qopt->limit, b1), - sprint_size(qopt->qth_min, b2), - sprint_size(qopt->qth_max, b3)); - fprintf(f, "ewma %u Plog %u Scell_log %u", - qopt->Wlog, qopt->Plog, qopt->Scell_log); - } - return 0; -} - -struct qdisc_util gred_qdisc_util = { - .id = "gred", - .parse_qopt = gred_parse_opt, - .print_qopt = gred_print_opt, -}; diff --git a/tc/q_hfsc.c b/tc/q_hfsc.c deleted file mode 100644 index f09c606..0000000 --- a/tc/q_hfsc.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * q_hfsc.c HFSC. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Patrick McHardy, <kaber@trash.net> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <math.h> - -#include "utils.h" -#include "tc_util.h" - -static int hfsc_get_sc(int *, char ***, struct tc_service_curve *); - - -static void -explain_qdisc(void) -{ - fprintf(stderr, - "Usage: ... hfsc [ default CLASSID ]\n" - "\n" - " default: default class for unclassified packets\n" - ); -} - -static void -explain_class(void) -{ - fprintf(stderr, - "Usage: ... hfsc [ [ rt SC ] [ ls SC ] | [ sc SC ] ] [ ul SC ]\n" - "\n" - "SC := [ [ m1 BPS ] [ d SEC ] m2 BPS\n" - "\n" - " m1 : slope of first segment\n" - " d : x-coordinate of intersection\n" - " m2 : slope of second segment\n" - "\n" - "Alternative format:\n" - "\n" - "SC := [ [ umax BYTE ] dmax SEC ] rate BPS\n" - "\n" - " umax : maximum unit of work\n" - " dmax : maximum delay\n" - " rate : rate\n" - "\n" - ); -} - -static void -explain1(char *arg) -{ - fprintf(stderr, "HFSC: Illegal \"%s\"\n", arg); -} - -static int -hfsc_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - struct tc_hfsc_qopt qopt; - - memset(&qopt, 0, sizeof(qopt)); - - while (argc > 0) { - if (matches(*argv, "default") == 0) { - NEXT_ARG(); - if (qopt.defcls != 0) { - fprintf(stderr, "HFSC: Double \"default\"\n"); - return -1; - } - if (get_u16(&qopt.defcls, *argv, 16) < 0) { - explain1("default"); - return -1; - } - } else if (matches(*argv, "help") == 0) { - explain_qdisc(); - return -1; - } else { - fprintf(stderr, "HFSC: What is \"%s\" ?\n", *argv); - explain_qdisc(); - return -1; - } - argc--, argv++; - } - - addattr_l(n, 1024, TCA_OPTIONS, &qopt, sizeof(qopt)); - return 0; -} - -static int -hfsc_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct tc_hfsc_qopt *qopt; - - if (opt == NULL) - return 0; - if (RTA_PAYLOAD(opt) < sizeof(*qopt)) - return -1; - qopt = RTA_DATA(opt); - - if (qopt->defcls != 0) - fprintf(f, "default %x ", qopt->defcls); - - return 0; -} - -static int -hfsc_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) -{ - struct tc_hfsc_stats *st; - - if (xstats == NULL) - return 0; - if (RTA_PAYLOAD(xstats) < sizeof(*st)) - return -1; - st = RTA_DATA(xstats); - - fprintf(f, " period %u ", st->period); - if (st->work != 0) - fprintf(f, "work %llu bytes ", (unsigned long long) st->work); - if (st->rtwork != 0) - fprintf(f, "rtwork %llu bytes ", (unsigned long long) st->rtwork); - fprintf(f, "level %u ", st->level); - fprintf(f, "\n"); - - return 0; -} - -static int -hfsc_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, - struct nlmsghdr *n) -{ - struct tc_service_curve rsc, fsc, usc; - int rsc_ok, fsc_ok, usc_ok; - struct rtattr *tail; - - memset(&rsc, 0, sizeof(rsc)); - memset(&fsc, 0, sizeof(fsc)); - memset(&usc, 0, sizeof(usc)); - rsc_ok = fsc_ok = usc_ok = 0; - - while (argc > 0) { - if (matches(*argv, "rt") == 0) { - NEXT_ARG(); - if (hfsc_get_sc(&argc, &argv, &rsc) < 0) { - explain1("rt"); - return -1; - } - rsc_ok = 1; - } else if (matches(*argv, "ls") == 0) { - NEXT_ARG(); - if (hfsc_get_sc(&argc, &argv, &fsc) < 0) { - explain1("ls"); - return -1; - } - fsc_ok = 1; - } else if (matches(*argv, "sc") == 0) { - NEXT_ARG(); - if (hfsc_get_sc(&argc, &argv, &rsc) < 0) { - explain1("sc"); - return -1; - } - memcpy(&fsc, &rsc, sizeof(fsc)); - rsc_ok = 1; - fsc_ok = 1; - } else if (matches(*argv, "ul") == 0) { - NEXT_ARG(); - if (hfsc_get_sc(&argc, &argv, &usc) < 0) { - explain1("ul"); - return -1; - } - usc_ok = 1; - } else if (matches(*argv, "help") == 0) { - explain_class(); - return -1; - } else { - fprintf(stderr, "HFSC: What is \"%s\" ?\n", *argv); - explain_class(); - return -1; - } - argc--, argv++; - } - - if (!(rsc_ok || fsc_ok || usc_ok)) { - fprintf(stderr, "HFSC: no parameters given\n"); - explain_class(); - return -1; - } - if (usc_ok && !fsc_ok) { - fprintf(stderr, "HFSC: Upper-limit Service Curve without " - "Link-Share Service Curve\n"); - explain_class(); - return -1; - } - - tail = NLMSG_TAIL(n); - - addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); - if (rsc_ok) - addattr_l(n, 1024, TCA_HFSC_RSC, &rsc, sizeof(rsc)); - if (fsc_ok) - addattr_l(n, 1024, TCA_HFSC_FSC, &fsc, sizeof(fsc)); - if (usc_ok) - addattr_l(n, 1024, TCA_HFSC_USC, &usc, sizeof(usc)); - - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - -static void -hfsc_print_sc(FILE *f, char *name, struct tc_service_curve *sc) -{ - SPRINT_BUF(b1); - - fprintf(f, "%s ", name); - fprintf(f, "m1 %s ", sprint_rate(sc->m1, b1)); - fprintf(f, "d %s ", sprint_usecs(sc->d, b1)); - fprintf(f, "m2 %s ", sprint_rate(sc->m2, b1)); -} - -static int -hfsc_print_class_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct rtattr *tb[TCA_HFSC_MAX+1]; - struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL; - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_HFSC_MAX, opt); - - if (tb[TCA_HFSC_RSC]) { - if (RTA_PAYLOAD(tb[TCA_HFSC_RSC]) < sizeof(*rsc)) - fprintf(stderr, "HFSC: truncated realtime option\n"); - else - rsc = RTA_DATA(tb[TCA_HFSC_RSC]); - } - if (tb[TCA_HFSC_FSC]) { - if (RTA_PAYLOAD(tb[TCA_HFSC_FSC]) < sizeof(*fsc)) - fprintf(stderr, "HFSC: truncated linkshare option\n"); - else - fsc = RTA_DATA(tb[TCA_HFSC_FSC]); - } - if (tb[TCA_HFSC_USC]) { - if (RTA_PAYLOAD(tb[TCA_HFSC_USC]) < sizeof(*usc)) - fprintf(stderr, "HFSC: truncated upperlimit option\n"); - else - usc = RTA_DATA(tb[TCA_HFSC_USC]); - } - - - if (rsc != NULL && fsc != NULL && - memcmp(rsc, fsc, sizeof(*rsc)) == 0) - hfsc_print_sc(f, "sc", rsc); - else { - if (rsc != NULL) - hfsc_print_sc(f, "rt", rsc); - if (fsc != NULL) - hfsc_print_sc(f, "ls", fsc); - } - if (usc != NULL) - hfsc_print_sc(f, "ul", usc); - - return 0; -} - -struct qdisc_util hfsc_qdisc_util = { - .id = "hfsc", - .parse_qopt = hfsc_parse_opt, - .print_qopt = hfsc_print_opt, - .print_xstats = hfsc_print_xstats, - .parse_copt = hfsc_parse_class_opt, - .print_copt = hfsc_print_class_opt, -}; - -static int -hfsc_get_sc1(int *argcp, char ***argvp, struct tc_service_curve *sc) -{ - char **argv = *argvp; - int argc = *argcp; - unsigned int m1 = 0, d = 0, m2 = 0; - - if (matches(*argv, "m1") == 0) { - NEXT_ARG(); - if (get_rate(&m1, *argv) < 0) { - explain1("m1"); - return -1; - } - NEXT_ARG(); - } - - if (matches(*argv, "d") == 0) { - NEXT_ARG(); - if (get_usecs(&d, *argv) < 0) { - explain1("d"); - return -1; - } - NEXT_ARG(); - } - - if (matches(*argv, "m2") == 0) { - NEXT_ARG(); - if (get_rate(&m2, *argv) < 0) { - explain1("m2"); - return -1; - } - } else - return -1; - - sc->m1 = m1; - sc->d = d; - sc->m2 = m2; - - *argvp = argv; - *argcp = argc; - return 0; -} - -static int -hfsc_get_sc2(int *argcp, char ***argvp, struct tc_service_curve *sc) -{ - char **argv = *argvp; - int argc = *argcp; - unsigned int umax = 0, dmax = 0, rate = 0; - - if (matches(*argv, "umax") == 0) { - NEXT_ARG(); - if (get_size(&umax, *argv) < 0) { - explain1("umax"); - return -1; - } - NEXT_ARG(); - } - - if (matches(*argv, "dmax") == 0) { - NEXT_ARG(); - if (get_usecs(&dmax, *argv) < 0) { - explain1("dmax"); - return -1; - } - NEXT_ARG(); - } - - if (matches(*argv, "rate") == 0) { - NEXT_ARG(); - if (get_rate(&rate, *argv) < 0) { - explain1("rate"); - return -1; - } - } else - return -1; - - if (umax != 0 && dmax == 0) { - fprintf(stderr, "HFSC: umax given but dmax is zero.\n"); - return -1; - } - - if (dmax != 0 && ceil(umax * 1000000.0 / dmax) > rate) { - /* - * concave curve, slope of first segment is umax/dmax, - * intersection is at dmax - */ - sc->m1 = ceil(umax * 1000000.0 / dmax); /* in bps */ - sc->d = dmax; - sc->m2 = rate; - } else { - /* - * convex curve, slope of first segment is 0, intersection - * is at dmax - umax / rate - */ - sc->m1 = 0; - sc->d = ceil(dmax - umax * 1000000.0 / rate); /* in usec */ - sc->m2 = rate; - } - - *argvp = argv; - *argcp = argc; - return 0; -} - -static int -hfsc_get_sc(int *argcp, char ***argvp, struct tc_service_curve *sc) -{ - if (hfsc_get_sc1(argcp, argvp, sc) < 0 && - hfsc_get_sc2(argcp, argvp, sc) < 0) - return -1; - - if (sc->m1 == 0 && sc->m2 == 0) { - fprintf(stderr, "HFSC: Service Curve has two zero slopes\n"); - return -1; - } - - return 0; -} diff --git a/tc/q_htb.c b/tc/q_htb.c deleted file mode 100644 index 828d4b1..0000000 --- a/tc/q_htb.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * q_htb.c HTB. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Martin Devera, devik@cdi.cz - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - -#define HTB_TC_VER 0x30003 -#if HTB_TC_VER >> 16 != TC_HTB_PROTOVER -#error "Different kernel and TC HTB versions" -#endif - -static void explain(void) -{ - fprintf(stderr, "Usage: ... qdisc add ... htb [default N] [r2q N]\n" - " default minor id of class to which unclassified packets are sent {0}\n" - " r2q DRR quantums are computed as rate in Bps/r2q {10}\n" - " debug string of 16 numbers each 0-3 {0}\n\n" - "... class add ... htb rate R1 [burst B1] [mpu B] [overhead O]\n" - " [prio P] [slot S] [pslot PS]\n" - " [ceil R2] [cburst B2] [mtu MTU] [quantum Q]\n" - " rate rate allocated to this class (class can still borrow)\n" - " burst max bytes burst which can be accumulated during idle period {computed}\n" - " mpu minimum packet size used in rate computations\n" - " overhead per-packet size overhead used in rate computations\n" - - " ceil definite upper class rate (no borrows) {rate}\n" - " cburst burst but for ceil {computed}\n" - " mtu max packet size we create rate map for {1600}\n" - " prio priority of leaf; lower are served first {0}\n" - " quantum how much bytes to serve from leaf at once {use r2q}\n" - "\nTC HTB version %d.%d\n",HTB_TC_VER>>16,HTB_TC_VER&0xffff - ); -} - -static void explain1(char *arg) -{ - fprintf(stderr, "Illegal \"%s\"\n", arg); - explain(); -} - - -#define usage() return(-1) - -static int htb_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - struct tc_htb_glob opt; - struct rtattr *tail; - unsigned i; char *p; - memset(&opt,0,sizeof(opt)); - opt.rate2quantum = 10; - opt.version = 3; - - while (argc > 0) { - if (matches(*argv, "r2q") == 0) { - NEXT_ARG(); - if (get_u32(&opt.rate2quantum, *argv, 10)) { - explain1("r2q"); return -1; - } - } else if (matches(*argv, "default") == 0) { - NEXT_ARG(); - if (get_u32(&opt.defcls, *argv, 16)) { - explain1("default"); return -1; - } - } else if (matches(*argv, "debug") == 0) { - NEXT_ARG(); p = *argv; - for (i=0; i<16; i++,p++) { - if (*p<'0' || *p>'3') break; - opt.debug |= (*p-'0')<<(2*i); - } - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - tail = NLMSG_TAIL(n); - addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); - addattr_l(n, 2024, TCA_HTB_INIT, &opt, NLMSG_ALIGN(sizeof(opt))); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - -static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - int ok=0; - struct tc_htb_opt opt; - __u32 rtab[256],ctab[256]; - unsigned buffer=0,cbuffer=0; - int cell_log=-1,ccell_log = -1; - unsigned mtu, mpu; - unsigned char mpu8 = 0, overhead = 0; - struct rtattr *tail; - - memset(&opt, 0, sizeof(opt)); mtu = 1600; /* eth packet len */ - - while (argc > 0) { - if (matches(*argv, "prio") == 0) { - NEXT_ARG(); - if (get_u32(&opt.prio, *argv, 10)) { - explain1("prio"); return -1; - } - ok++; - } else if (matches(*argv, "mtu") == 0) { - NEXT_ARG(); - if (get_u32(&mtu, *argv, 10)) { - explain1("mtu"); return -1; - } - } else if (matches(*argv, "mpu") == 0) { - NEXT_ARG(); - if (get_u8(&mpu8, *argv, 10)) { - explain1("mpu"); return -1; - } - } else if (matches(*argv, "overhead") == 0) { - NEXT_ARG(); - if (get_u8(&overhead, *argv, 10)) { - explain1("overhead"); return -1; - } - } else if (matches(*argv, "quantum") == 0) { - NEXT_ARG(); - if (get_u32(&opt.quantum, *argv, 10)) { - explain1("quantum"); return -1; - } - } else if (matches(*argv, "burst") == 0 || - strcmp(*argv, "buffer") == 0 || - strcmp(*argv, "maxburst") == 0) { - NEXT_ARG(); - if (get_size_and_cell(&buffer, &cell_log, *argv) < 0) { - explain1("buffer"); - return -1; - } - ok++; - } else if (matches(*argv, "cburst") == 0 || - strcmp(*argv, "cbuffer") == 0 || - strcmp(*argv, "cmaxburst") == 0) { - NEXT_ARG(); - if (get_size_and_cell(&cbuffer, &ccell_log, *argv) < 0) { - explain1("cbuffer"); - return -1; - } - ok++; - } else if (strcmp(*argv, "ceil") == 0) { - NEXT_ARG(); - if (opt.ceil.rate) { - fprintf(stderr, "Double \"ceil\" spec\n"); - return -1; - } - if (get_rate(&opt.ceil.rate, *argv)) { - explain1("ceil"); - return -1; - } - ok++; - } else if (strcmp(*argv, "rate") == 0) { - NEXT_ARG(); - if (opt.rate.rate) { - fprintf(stderr, "Double \"rate\" spec\n"); - return -1; - } - if (get_rate(&opt.rate.rate, *argv)) { - explain1("rate"); - return -1; - } - ok++; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - -/* if (!ok) - return 0;*/ - - if (opt.rate.rate == 0) { - fprintf(stderr, "\"rate\" is required.\n"); - return -1; - } - /* if ceil params are missing, use the same as rate */ - if (!opt.ceil.rate) opt.ceil = opt.rate; - - /* compute minimal allowed burst from rate; mtu is added here to make - sute that buffer is larger than mtu and to have some safeguard space */ - if (!buffer) buffer = opt.rate.rate / get_hz() + mtu; - if (!cbuffer) cbuffer = opt.ceil.rate / get_hz() + mtu; - -/* encode overhead and mpu, 8 bits each, into lower 16 bits */ - mpu = (unsigned)mpu8 | (unsigned)overhead << 8; - opt.ceil.mpu = mpu; opt.rate.mpu = mpu; - - if ((cell_log = tc_calc_rtable(opt.rate.rate, rtab, cell_log, mtu, mpu)) < 0) { - fprintf(stderr, "htb: failed to calculate rate table.\n"); - return -1; - } - opt.buffer = tc_calc_xmittime(opt.rate.rate, buffer); - opt.rate.cell_log = cell_log; - - if ((ccell_log = tc_calc_rtable(opt.ceil.rate, ctab, cell_log, mtu, mpu)) < 0) { - fprintf(stderr, "htb: failed to calculate ceil rate table.\n"); - return -1; - } - opt.cbuffer = tc_calc_xmittime(opt.ceil.rate, cbuffer); - opt.ceil.cell_log = ccell_log; - - tail = NLMSG_TAIL(n); - addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); - addattr_l(n, 2024, TCA_HTB_PARMS, &opt, sizeof(opt)); - addattr_l(n, 3024, TCA_HTB_RTAB, rtab, 1024); - addattr_l(n, 4024, TCA_HTB_CTAB, ctab, 1024); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - -static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct rtattr *tb[TCA_HTB_RTAB+1]; - struct tc_htb_opt *hopt; - struct tc_htb_glob *gopt; - double buffer,cbuffer; - SPRINT_BUF(b1); - SPRINT_BUF(b2); - SPRINT_BUF(b3); - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_HTB_RTAB, opt); - - if (tb[TCA_HTB_PARMS]) { - - hopt = RTA_DATA(tb[TCA_HTB_PARMS]); - if (RTA_PAYLOAD(tb[TCA_HTB_PARMS]) < sizeof(*hopt)) return -1; - - if (!hopt->level) { - fprintf(f, "prio %d ", (int)hopt->prio); - if (show_details) - fprintf(f, "quantum %d ", (int)hopt->quantum); - } - fprintf(f, "rate %s ", sprint_rate(hopt->rate.rate, b1)); - buffer = ((double)hopt->rate.rate*tc_core_tick2usec(hopt->buffer))/1000000; - fprintf(f, "ceil %s ", sprint_rate(hopt->ceil.rate, b1)); - cbuffer = ((double)hopt->ceil.rate*tc_core_tick2usec(hopt->cbuffer))/1000000; - if (show_details) { - fprintf(f, "burst %s/%u mpu %s overhead %s ", - sprint_size(buffer, b1), - 1<<hopt->rate.cell_log, - sprint_size(hopt->rate.mpu&0xFF, b2), - sprint_size((hopt->rate.mpu>>8)&0xFF, b3)); - fprintf(f, "cburst %s/%u mpu %s overhead %s ", - sprint_size(cbuffer, b1), - 1<<hopt->ceil.cell_log, - sprint_size(hopt->ceil.mpu&0xFF, b2), - sprint_size((hopt->ceil.mpu>>8)&0xFF, b3)); - fprintf(f, "level %d ", (int)hopt->level); - } else { - fprintf(f, "burst %s ", sprint_size(buffer, b1)); - fprintf(f, "cburst %s ", sprint_size(cbuffer, b1)); - } - if (show_raw) - fprintf(f, "buffer [%08x] cbuffer [%08x] ", - hopt->buffer,hopt->cbuffer); - } - if (tb[TCA_HTB_INIT]) { - gopt = RTA_DATA(tb[TCA_HTB_INIT]); - if (RTA_PAYLOAD(tb[TCA_HTB_INIT]) < sizeof(*gopt)) return -1; - - fprintf(f, "r2q %d default %x direct_packets_stat %u", - gopt->rate2quantum,gopt->defcls,gopt->direct_pkts); - if (show_details) - fprintf(f," ver %d.%d",gopt->version >> 16,gopt->version & 0xffff); - } - return 0; -} - -static int htb_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) -{ - struct tc_htb_xstats *st; - if (xstats == NULL) - return 0; - - if (RTA_PAYLOAD(xstats) < sizeof(*st)) - return -1; - - st = RTA_DATA(xstats); - fprintf(f, " lended: %u borrowed: %u giants: %u\n", - st->lends,st->borrows,st->giants); - fprintf(f, " tokens: %d ctokens: %d\n", st->tokens,st->ctokens); - return 0; -} - -struct qdisc_util htb_qdisc_util = { - .id = "htb", - .parse_qopt = htb_parse_opt, - .print_qopt = htb_print_opt, - .print_xstats = htb_print_xstats, - .parse_copt = htb_parse_class_opt, - .print_copt = htb_print_opt, -}; - -/* for testing of old one */ -struct qdisc_util htb2_qdisc_util = { - .id = "htb2", - .parse_qopt = htb_parse_opt, - .print_qopt = htb_print_opt, - .print_xstats = htb_print_xstats, - .parse_copt = htb_parse_class_opt, - .print_copt = htb_print_opt, -}; diff --git a/tc/q_ingress.c b/tc/q_ingress.c deleted file mode 100644 index 71fbd49..0000000 --- a/tc/q_ingress.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * - * q_ingress.c INGRESS. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: J Hadi Salim - * - * This is here just in case it is needed - * useless right now; might be useful in the future - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - -static void explain(void) -{ - fprintf(stderr, "Usage: ... ingress \n"); -} - -#define usage() return(-1) - -static int ingress_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - - if (argc > 0) { - while (argc > 0) { - - if (strcmp(*argv, "handle") == 0) { - NEXT_ARG(); - argc--; argv++; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - } - } - - addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); - return 0; -} - -static int ingress_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - - fprintf(f, "---------------- "); - return 0; -} - -struct qdisc_util ingress_qdisc_util = { - .id = "ingress", - .parse_qopt = ingress_parse_opt, - .print_qopt = ingress_print_opt, -}; diff --git a/tc/q_netem.c b/tc/q_netem.c deleted file mode 100644 index 757edca..0000000 --- a/tc/q_netem.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * q_netem.c NETEM. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Stephen Hemminger <shemminger@osdl.org> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <errno.h> - -#include "utils.h" -#include "tc_util.h" -#include "tc_common.h" - -static void explain(void) -{ - fprintf(stderr, -"Usage: ... netem [ limit PACKETS ] \n" \ -" [ delay TIME [ JITTER [CORRELATION]]]\n" \ -" [ distribution {uniform|normal|pareto|paretonormal} ]\n" \ -" [ drop PERCENT [CORRELATION]] \n" \ -" [ corrupt PERCENT [CORRELATION]] \n" \ -" [ duplicate PERCENT [CORRELATION]]\n" \ -" [ reorder PRECENT [CORRELATION] [ gap DISTANCE ]]\n"); -} - -static void explain1(const char *arg) -{ - fprintf(stderr, "Illegal \"%s\"\n", arg); -} - -#define usage() return(-1) - -/* - * Simplistic file parser for distrbution data. - * Format is: - * # comment line(s) - * data0 data1 - */ -#define MAXDIST 65536 -static int get_distribution(const char *type, __s16 *data) -{ - FILE *f; - int n; - long x; - size_t len; - char *line = NULL; - char name[128]; - - snprintf(name, sizeof(name), "/usr/lib/tc/%s.dist", type); - if ((f = fopen(name, "r")) == NULL) { - fprintf(stderr, "No distribution data for %s (%s: %s)\n", - type, name, strerror(errno)); - return -1; - } - - n = 0; - while (getline(&line, &len, f) != -1) { - char *p, *endp; - if (*line == '\n' || *line == '#') - continue; - - for (p = line; ; p = endp) { - x = strtol(p, &endp, 0); - if (endp == p) - break; - - if (n >= MAXDIST) { - fprintf(stderr, "%s: too much data\n", - name); - n = -1; - goto error; - } - data[n++] = x; - } - } - error: - free(line); - fclose(f); - return n; -} - -static int isnumber(const char *arg) -{ - char *p; - (void) strtod(arg, &p); - return (p != arg); -} - -#define NEXT_IS_NUMBER() (NEXT_ARG_OK() && isnumber(argv[1])) - -/* Adjust for the fact that psched_ticks aren't always usecs - (based on kernel PSCHED_CLOCK configuration */ -static int get_ticks(__u32 *ticks, const char *str) -{ - unsigned t; - - if(get_usecs(&t, str)) - return -1; - - *ticks = tc_core_usec2tick(t); - return 0; -} - -static char *sprint_ticks(__u32 ticks, char *buf) -{ - return sprint_usecs(tc_core_tick2usec(ticks), buf); -} - - -static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv, - struct nlmsghdr *n) -{ - size_t dist_size = 0; - struct rtattr *tail; - struct tc_netem_qopt opt; - struct tc_netem_corr cor; - struct tc_netem_reorder reorder; - struct tc_netem_corrupt corrupt; - __s16 *dist_data = NULL; - - memset(&opt, 0, sizeof(opt)); - opt.limit = 1000; - memset(&cor, 0, sizeof(cor)); - memset(&reorder, 0, sizeof(reorder)); - memset(&corrupt, 0, sizeof(corrupt)); - - while (argc > 0) { - if (matches(*argv, "limit") == 0) { - NEXT_ARG(); - if (get_size(&opt.limit, *argv)) { - explain1("limit"); - return -1; - } - } else if (matches(*argv, "latency") == 0 || - matches(*argv, "delay") == 0) { - NEXT_ARG(); - if (get_ticks(&opt.latency, *argv)) { - explain1("latency"); - return -1; - } - - if (NEXT_IS_NUMBER()) { - NEXT_ARG(); - if (get_ticks(&opt.jitter, *argv)) { - explain1("latency"); - return -1; - } - - if (NEXT_IS_NUMBER()) { - NEXT_ARG(); - if (get_percent(&cor.delay_corr, - *argv)) { - explain1("latency"); - return -1; - } - } - } - } else if (matches(*argv, "loss") == 0 || - matches(*argv, "drop") == 0) { - NEXT_ARG(); - if (get_percent(&opt.loss, *argv)) { - explain1("loss"); - return -1; - } - if (NEXT_IS_NUMBER()) { - NEXT_ARG(); - if (get_percent(&cor.loss_corr, *argv)) { - explain1("loss"); - return -1; - } - } - } else if (matches(*argv, "reorder") == 0) { - NEXT_ARG(); - if (get_percent(&reorder.probability, *argv)) { - explain1("reorder"); - return -1; - } - if (NEXT_IS_NUMBER()) { - NEXT_ARG(); - if (get_percent(&reorder.correlation, *argv)) { - explain1("reorder"); - return -1; - } - } - } else if (matches(*argv, "corrupt") == 0) { - NEXT_ARG(); - if (get_percent(&corrupt.probability, *argv)) { - explain1("corrupt"); - return -1; - } - if (NEXT_IS_NUMBER()) { - NEXT_ARG(); - if (get_percent(&corrupt.correlation, *argv)) { - explain1("corrupt"); - return -1; - } - } - } else if (matches(*argv, "gap") == 0) { - NEXT_ARG(); - if (get_u32(&opt.gap, *argv, 0)) { - explain1("gap"); - return -1; - } - } else if (matches(*argv, "duplicate") == 0) { - NEXT_ARG(); - if (get_percent(&opt.duplicate, *argv)) { - explain1("duplicate"); - return -1; - } - if (NEXT_IS_NUMBER()) { - NEXT_ARG(); - if (get_percent(&cor.dup_corr, *argv)) { - explain1("duplicate"); - return -1; - } - } - } else if (matches(*argv, "distribution") == 0) { - NEXT_ARG(); - dist_data = alloca(MAXDIST); - dist_size = get_distribution(*argv, dist_data); - if (dist_size < 0) - return -1; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - - tail = NLMSG_TAIL(n); - - if (reorder.probability) { - if (opt.latency == 0) { - fprintf(stderr, "reordering not possible without specifying some delay\n"); - } - if (opt.gap == 0) - opt.gap = 1; - } else if (opt.gap > 0) { - fprintf(stderr, "gap specified without reorder probability\n"); - explain(); - return -1; - } - - if (dist_data && (opt.latency == 0 || opt.jitter == 0)) { - fprintf(stderr, "distribution specified but no latency and jitter values\n"); - explain(); - return -1; - } - - if (addattr_l(n, TCA_BUF_MAX, TCA_OPTIONS, &opt, sizeof(opt)) < 0) - return -1; - - if (cor.delay_corr || cor.loss_corr || cor.dup_corr) { - if (addattr_l(n, TCA_BUF_MAX, TCA_NETEM_CORR, &cor, sizeof(cor)) < 0) - return -1; - } - - if (addattr_l(n, TCA_BUF_MAX, TCA_NETEM_REORDER, &reorder, sizeof(reorder)) < 0) - return -1; - - if (corrupt.probability) { - if (addattr_l(n, TCA_BUF_MAX, TCA_NETEM_CORRUPT, &corrupt, sizeof(corrupt)) < 0) - return -1; - } - - if (dist_data) { - if (addattr_l(n, 32768, TCA_NETEM_DELAY_DIST, - dist_data, dist_size*sizeof(dist_data[0])) < 0) - return -1; - } - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - -static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - const struct tc_netem_corr *cor = NULL; - const struct tc_netem_reorder *reorder = NULL; - const struct tc_netem_corrupt *corrupt = NULL; - struct tc_netem_qopt qopt; - int len = RTA_PAYLOAD(opt) - sizeof(qopt); - SPRINT_BUF(b1); - - if (opt == NULL) - return 0; - - if (len < 0) { - fprintf(stderr, "options size error\n"); - return -1; - } - memcpy(&qopt, RTA_DATA(opt), sizeof(qopt)); - - if (len > 0) { - struct rtattr *tb[TCA_NETEM_MAX+1]; - parse_rtattr(tb, TCA_NETEM_MAX, RTA_DATA(opt) + sizeof(qopt), - len); - - if (tb[TCA_NETEM_CORR]) { - if (RTA_PAYLOAD(tb[TCA_NETEM_CORR]) < sizeof(*cor)) - return -1; - cor = RTA_DATA(tb[TCA_NETEM_CORR]); - } - if (tb[TCA_NETEM_REORDER]) { - if (RTA_PAYLOAD(tb[TCA_NETEM_REORDER]) < sizeof(*reorder)) - return -1; - reorder = RTA_DATA(tb[TCA_NETEM_REORDER]); - } - if (tb[TCA_NETEM_CORRUPT]) { - if (RTA_PAYLOAD(tb[TCA_NETEM_CORRUPT]) < sizeof(*corrupt)) - return -1; - corrupt = RTA_DATA(tb[TCA_NETEM_CORRUPT]); - } - } - - fprintf(f, "limit %d", qopt.limit); - - if (qopt.latency) { - fprintf(f, " delay %s", sprint_ticks(qopt.latency, b1)); - - if (qopt.jitter) { - fprintf(f, " %s", sprint_ticks(qopt.jitter, b1)); - if (cor && cor->delay_corr) - fprintf(f, " %s", sprint_percent(cor->delay_corr, b1)); - } - } - - if (qopt.loss) { - fprintf(f, " loss %s", sprint_percent(qopt.loss, b1)); - if (cor && cor->loss_corr) - fprintf(f, " %s", sprint_percent(cor->loss_corr, b1)); - } - - if (qopt.duplicate) { - fprintf(f, " duplicate %s", - sprint_percent(qopt.duplicate, b1)); - if (cor && cor->dup_corr) - fprintf(f, " %s", sprint_percent(cor->dup_corr, b1)); - } - - if (reorder && reorder->probability) { - fprintf(f, " reorder %s", - sprint_percent(reorder->probability, b1)); - if (reorder->correlation) - fprintf(f, " %s", - sprint_percent(reorder->correlation, b1)); - } - - if (corrupt && corrupt->probability) { - fprintf(f, " corrupt %s", - sprint_percent(corrupt->probability, b1)); - if (corrupt->correlation) - fprintf(f, " %s", - sprint_percent(corrupt->correlation, b1)); - } - - if (qopt.gap) - fprintf(f, " gap %lu", (unsigned long)qopt.gap); - - return 0; -} - -struct qdisc_util netem_qdisc_util = { - .id = "netem", - .parse_qopt = netem_parse_opt, - .print_qopt = netem_print_opt, -}; - diff --git a/tc/q_prio.c b/tc/q_prio.c deleted file mode 100644 index d696e1b..0000000 --- a/tc/q_prio.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * q_prio.c PRIO. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - * Changes: - * - * Ole Husgaard <sparre@login.dknet.dk>: 990513: prio2band map was always reset. - * J Hadi Salim <hadi@cyberus.ca>: 990609: priomap fix. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - -static void explain(void) -{ - fprintf(stderr, "Usage: ... prio bands NUMBER priomap P1 P2...\n"); -} - -#define usage() return(-1) - -static int prio_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - int ok=0; - int pmap_mode = 0; - int idx = 0; - struct tc_prio_qopt opt={3,{ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }}; - - while (argc > 0) { - if (strcmp(*argv, "bands") == 0) { - if (pmap_mode) - explain(); - NEXT_ARG(); - if (get_integer(&opt.bands, *argv, 10)) { - fprintf(stderr, "Illegal \"bands\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "priomap") == 0) { - if (pmap_mode) { - fprintf(stderr, "Error: duplicate priomap\n"); - return -1; - } - pmap_mode = 1; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - unsigned band; - if (!pmap_mode) { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - if (get_unsigned(&band, *argv, 10)) { - fprintf(stderr, "Illegal \"priomap\" element\n"); - return -1; - } - if (band > opt.bands) { - fprintf(stderr, "\"priomap\" element is out of bands\n"); - return -1; - } - if (idx > TC_PRIO_MAX) { - fprintf(stderr, "\"priomap\" index > TC_PRIO_MAX=%u\n", TC_PRIO_MAX); - return -1; - } - opt.priomap[idx++] = band; - } - argc--; argv++; - } - -/* - if (pmap_mode) { - for (; idx < TC_PRIO_MAX; idx++) - opt.priomap[idx] = opt.priomap[TC_PRIO_BESTEFFORT]; - } -*/ - addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt)); - return 0; -} - -int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - int i; - struct tc_prio_qopt *qopt; - - if (opt == NULL) - return 0; - - if (RTA_PAYLOAD(opt) < sizeof(*qopt)) - return -1; - qopt = RTA_DATA(opt); - fprintf(f, "bands %u priomap ", qopt->bands); - for (i=0; i<=TC_PRIO_MAX; i++) - fprintf(f, " %d", qopt->priomap[i]); - return 0; -} - -struct qdisc_util prio_qdisc_util = { - .id = "prio", - .parse_qopt = prio_parse_opt, - .print_qopt = prio_print_opt, -}; - diff --git a/tc/q_red.c b/tc/q_red.c deleted file mode 100644 index 1743f6c..0000000 --- a/tc/q_red.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * q_red.c RED. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - -#include "tc_red.h" - -static void explain(void) -{ - fprintf(stderr, "Usage: ... red limit BYTES min BYTES max BYTES avpkt BYTES burst PACKETS\n"); - fprintf(stderr, " probability PROBABILITY bandwidth KBPS [ ecn ]\n"); -} - -#define usage() return(-1) - -static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - int ok=0; - struct tc_red_qopt opt; - unsigned burst = 0; - unsigned avpkt = 0; - double probability = 0.02; - unsigned rate = 0; - int ecn_ok = 0; - int wlog; - __u8 sbuf[256]; - struct rtattr *tail; - - memset(&opt, 0, sizeof(opt)); - - while (argc > 0) { - if (strcmp(*argv, "limit") == 0) { - NEXT_ARG(); - if (get_size(&opt.limit, *argv)) { - fprintf(stderr, "Illegal \"limit\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "min") == 0) { - NEXT_ARG(); - if (get_size(&opt.qth_min, *argv)) { - fprintf(stderr, "Illegal \"min\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "max") == 0) { - NEXT_ARG(); - if (get_size(&opt.qth_max, *argv)) { - fprintf(stderr, "Illegal \"max\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "burst") == 0) { - NEXT_ARG(); - if (get_unsigned(&burst, *argv, 0)) { - fprintf(stderr, "Illegal \"burst\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "avpkt") == 0) { - NEXT_ARG(); - if (get_size(&avpkt, *argv)) { - fprintf(stderr, "Illegal \"avpkt\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "probability") == 0) { - NEXT_ARG(); - if (sscanf(*argv, "%lg", &probability) != 1) { - fprintf(stderr, "Illegal \"probability\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "bandwidth") == 0) { - NEXT_ARG(); - if (get_rate(&rate, *argv)) { - fprintf(stderr, "Illegal \"bandwidth\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "ecn") == 0) { - ecn_ok = 1; - ok++; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - - if (!ok) - return 0; - - if (rate == 0) - get_rate(&rate, "10Mbit"); - - if (!opt.qth_min || !opt.qth_max || !burst || !opt.limit || !avpkt) { - fprintf(stderr, "Required parameter (min, max, burst, limit, avpket) is missing\n"); - return -1; - } - - if ((wlog = tc_red_eval_ewma(opt.qth_min, burst, avpkt)) < 0) { - fprintf(stderr, "RED: failed to calculate EWMA constant.\n"); - return -1; - } - if (wlog >= 10) - fprintf(stderr, "RED: WARNING. Burst %d seems to be to large.\n", burst); - opt.Wlog = wlog; - if ((wlog = tc_red_eval_P(opt.qth_min, opt.qth_max, probability)) < 0) { - fprintf(stderr, "RED: failed to calculate probability.\n"); - return -1; - } - opt.Plog = wlog; - if ((wlog = tc_red_eval_idle_damping(opt.Wlog, avpkt, rate, sbuf)) < 0) { - fprintf(stderr, "RED: failed to calculate idle damping table.\n"); - return -1; - } - opt.Scell_log = wlog; - if (ecn_ok) { -#ifdef TC_RED_ECN - opt.flags |= TC_RED_ECN; -#else - fprintf(stderr, "RED: ECN support is missing in this binary.\n"); - return -1; -#endif - } - - tail = NLMSG_TAIL(n); - addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); - addattr_l(n, 1024, TCA_RED_PARMS, &opt, sizeof(opt)); - addattr_l(n, 1024, TCA_RED_STAB, sbuf, 256); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - -static int red_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct rtattr *tb[TCA_RED_STAB+1]; - struct tc_red_qopt *qopt; - SPRINT_BUF(b1); - SPRINT_BUF(b2); - SPRINT_BUF(b3); - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_RED_STAB, opt); - - if (tb[TCA_RED_PARMS] == NULL) - return -1; - qopt = RTA_DATA(tb[TCA_RED_PARMS]); - if (RTA_PAYLOAD(tb[TCA_RED_PARMS]) < sizeof(*qopt)) - return -1; - fprintf(f, "limit %s min %s max %s ", - sprint_size(qopt->limit, b1), - sprint_size(qopt->qth_min, b2), - sprint_size(qopt->qth_max, b3)); -#ifdef TC_RED_ECN - if (qopt->flags & TC_RED_ECN) - fprintf(f, "ecn "); -#endif - if (show_details) { - fprintf(f, "ewma %u Plog %u Scell_log %u", - qopt->Wlog, qopt->Plog, qopt->Scell_log); - } - return 0; -} - -static int red_print_xstats(struct qdisc_util *qu, FILE *f, struct rtattr *xstats) -{ -#ifdef TC_RED_ECN - struct tc_red_xstats *st; - - if (xstats == NULL) - return 0; - - if (RTA_PAYLOAD(xstats) < sizeof(*st)) - return -1; - - st = RTA_DATA(xstats); - fprintf(f, " marked %u early %u pdrop %u other %u", - st->marked, st->early, st->pdrop, st->other); - return 0; - -#endif - return 0; -} - - -struct qdisc_util red_qdisc_util = { - .id = "red", - .parse_qopt = red_parse_opt, - .print_qopt = red_print_opt, - .print_xstats = red_print_xstats, -}; diff --git a/tc/q_sfq.c b/tc/q_sfq.c deleted file mode 100644 index 05385cf..0000000 --- a/tc/q_sfq.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * q_sfq.c SFQ. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - -static void explain(void) -{ - fprintf(stderr, "Usage: ... sfq [ limit NUMBER ] [ perturb SECS ] [ quantum BYTES ]\n"); -} - -#define usage() return(-1) - -static int sfq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - int ok=0; - struct tc_sfq_qopt opt; - - memset(&opt, 0, sizeof(opt)); - - while (argc > 0) { - if (strcmp(*argv, "quantum") == 0) { - NEXT_ARG(); - if (get_size(&opt.quantum, *argv)) { - fprintf(stderr, "Illegal \"limit\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "perturb") == 0) { - NEXT_ARG(); - if (get_integer(&opt.perturb_period, *argv, 0)) { - fprintf(stderr, "Illegal \"perturb\"\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "limit") == 0) { - NEXT_ARG(); - if (get_u32(&opt.limit, *argv, 0)) { - fprintf(stderr, "Illegal \"limit\"\n"); - return -1; - } - if (opt.limit < 2) { - fprintf(stderr, "Illegal \"limit\", must be > 1\n"); - return -1; - } - ok++; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - - if (ok) - addattr_l(n, 1024, TCA_OPTIONS, &opt, sizeof(opt)); - return 0; -} - -static int sfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct tc_sfq_qopt *qopt; - SPRINT_BUF(b1); - - if (opt == NULL) - return 0; - - if (RTA_PAYLOAD(opt) < sizeof(*qopt)) - return -1; - qopt = RTA_DATA(opt); - fprintf(f, "limit %up ", qopt->limit); - fprintf(f, "quantum %s ", sprint_size(qopt->quantum, b1)); - if (show_details) { - fprintf(f, "flows %u/%u ", qopt->flows, qopt->divisor); - } - if (qopt->perturb_period) - fprintf(f, "perturb %dsec ", qopt->perturb_period); - return 0; -} - -struct qdisc_util sfq_qdisc_util = { - .id = "sfq", - .parse_qopt = sfq_parse_opt, - .print_qopt = sfq_print_opt, -}; diff --git a/tc/q_tbf.c b/tc/q_tbf.c deleted file mode 100644 index 6ed5e0b..0000000 --- a/tc/q_tbf.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * q_tbf.c TBF. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "utils.h" -#include "tc_util.h" - -static void explain(void) -{ - fprintf(stderr, "Usage: ... tbf limit BYTES burst BYTES[/BYTES] rate KBPS [ mtu BYTES[/BYTES] ]\n"); - fprintf(stderr, " [ peakrate KBPS ] [ latency TIME ]\n"); -} - -static void explain1(char *arg) -{ - fprintf(stderr, "Illegal \"%s\"\n", arg); -} - - -#define usage() return(-1) - -static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - int ok=0; - struct tc_tbf_qopt opt; - __u32 rtab[256]; - __u32 ptab[256]; - unsigned buffer=0, mtu=0, mpu=0, latency=0; - int Rcell_log=-1, Pcell_log = -1; - struct rtattr *tail; - - memset(&opt, 0, sizeof(opt)); - - while (argc > 0) { - if (matches(*argv, "limit") == 0) { - NEXT_ARG(); - if (opt.limit || latency) { - fprintf(stderr, "Double \"limit/latency\" spec\n"); - return -1; - } - if (get_size(&opt.limit, *argv)) { - explain1("limit"); - return -1; - } - ok++; - } else if (matches(*argv, "latency") == 0) { - NEXT_ARG(); - if (opt.limit || latency) { - fprintf(stderr, "Double \"limit/latency\" spec\n"); - return -1; - } - if (get_usecs(&latency, *argv)) { - explain1("latency"); - return -1; - } - ok++; - } else if (matches(*argv, "burst") == 0 || - strcmp(*argv, "buffer") == 0 || - strcmp(*argv, "maxburst") == 0) { - NEXT_ARG(); - if (buffer) { - fprintf(stderr, "Double \"buffer/burst\" spec\n"); - return -1; - } - if (get_size_and_cell(&buffer, &Rcell_log, *argv) < 0) { - explain1("buffer"); - return -1; - } - ok++; - } else if (strcmp(*argv, "mtu") == 0 || - strcmp(*argv, "minburst") == 0) { - NEXT_ARG(); - if (mtu) { - fprintf(stderr, "Double \"mtu/minburst\" spec\n"); - return -1; - } - if (get_size_and_cell(&mtu, &Pcell_log, *argv) < 0) { - explain1("mtu"); - return -1; - } - ok++; - } else if (strcmp(*argv, "mpu") == 0) { - NEXT_ARG(); - if (mpu) { - fprintf(stderr, "Double \"mpu\" spec\n"); - return -1; - } - if (get_size(&mpu, *argv)) { - explain1("mpu"); - return -1; - } - ok++; - } else if (strcmp(*argv, "rate") == 0) { - NEXT_ARG(); - if (opt.rate.rate) { - fprintf(stderr, "Double \"rate\" spec\n"); - return -1; - } - if (get_rate(&opt.rate.rate, *argv)) { - explain1("rate"); - return -1; - } - ok++; - } else if (matches(*argv, "peakrate") == 0) { - NEXT_ARG(); - if (opt.peakrate.rate) { - fprintf(stderr, "Double \"peakrate\" spec\n"); - return -1; - } - if (get_rate(&opt.peakrate.rate, *argv)) { - explain1("peakrate"); - return -1; - } - ok++; - } else if (strcmp(*argv, "help") == 0) { - explain(); - return -1; - } else { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; - } - argc--; argv++; - } - - if (!ok) - return 0; - - if (opt.rate.rate == 0 || !buffer) { - fprintf(stderr, "Both \"rate\" and \"burst\" are required.\n"); - return -1; - } - if (opt.peakrate.rate) { - if (!mtu) { - fprintf(stderr, "\"mtu\" is required, if \"peakrate\" is requested.\n"); - return -1; - } - } - - if (opt.limit == 0 && latency == 0) { - fprintf(stderr, "Either \"limit\" or \"latency\" are required.\n"); - return -1; - } - - if (opt.limit == 0) { - double lim = opt.rate.rate*(double)latency/1000000 + buffer; - if (opt.peakrate.rate) { - double lim2 = opt.peakrate.rate*(double)latency/1000000 + mtu; - if (lim2 < lim) - lim = lim2; - } - opt.limit = lim; - } - - if ((Rcell_log = tc_calc_rtable(opt.rate.rate, rtab, Rcell_log, mtu, mpu)) < 0) { - fprintf(stderr, "TBF: failed to calculate rate table.\n"); - return -1; - } - opt.buffer = tc_calc_xmittime(opt.rate.rate, buffer); - opt.rate.cell_log = Rcell_log; - opt.rate.mpu = mpu; - if (opt.peakrate.rate) { - if ((Pcell_log = tc_calc_rtable(opt.peakrate.rate, ptab, Pcell_log, mtu, mpu)) < 0) { - fprintf(stderr, "TBF: failed to calculate peak rate table.\n"); - return -1; - } - opt.mtu = tc_calc_xmittime(opt.peakrate.rate, mtu); - opt.peakrate.cell_log = Pcell_log; - opt.peakrate.mpu = mpu; - } - - tail = NLMSG_TAIL(n); - addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); - addattr_l(n, 2024, TCA_TBF_PARMS, &opt, sizeof(opt)); - addattr_l(n, 3024, TCA_TBF_RTAB, rtab, 1024); - if (opt.peakrate.rate) - addattr_l(n, 4096, TCA_TBF_PTAB, ptab, 1024); - tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; - return 0; -} - -static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) -{ - struct rtattr *tb[TCA_TBF_PTAB+1]; - struct tc_tbf_qopt *qopt; - double buffer, mtu; - double latency; - SPRINT_BUF(b1); - SPRINT_BUF(b2); - - if (opt == NULL) - return 0; - - parse_rtattr_nested(tb, TCA_TBF_PTAB, opt); - - if (tb[TCA_TBF_PARMS] == NULL) - return -1; - - qopt = RTA_DATA(tb[TCA_TBF_PARMS]); - if (RTA_PAYLOAD(tb[TCA_TBF_PARMS]) < sizeof(*qopt)) - return -1; - fprintf(f, "rate %s ", sprint_rate(qopt->rate.rate, b1)); - buffer = ((double)qopt->rate.rate*tc_core_tick2usec(qopt->buffer))/1000000; - if (show_details) { - fprintf(f, "burst %s/%u mpu %s ", sprint_size(buffer, b1), - 1<<qopt->rate.cell_log, sprint_size(qopt->rate.mpu, b2)); - } else { - fprintf(f, "burst %s ", sprint_size(buffer, b1)); - } - if (show_raw) - fprintf(f, "[%08x] ", qopt->buffer); - if (qopt->peakrate.rate) { - fprintf(f, "peakrate %s ", sprint_rate(qopt->peakrate.rate, b1)); - if (qopt->mtu || qopt->peakrate.mpu) { - mtu = ((double)qopt->peakrate.rate*tc_core_tick2usec(qopt->mtu))/1000000; - if (show_details) { - fprintf(f, "mtu %s/%u mpu %s ", sprint_size(mtu, b1), - 1<<qopt->peakrate.cell_log, sprint_size(qopt->peakrate.mpu, b2)); - } else { - fprintf(f, "minburst %s ", sprint_size(mtu, b1)); - } - if (show_raw) - fprintf(f, "[%08x] ", qopt->mtu); - } - } - - if (show_raw) - fprintf(f, "limit %s ", sprint_size(qopt->limit, b1)); - - latency = 1000000*(qopt->limit/(double)qopt->rate.rate) - tc_core_tick2usec(qopt->buffer); - if (qopt->peakrate.rate) { - double lat2 = 1000000*(qopt->limit/(double)qopt->peakrate.rate) - tc_core_tick2usec(qopt->mtu); - if (lat2 > latency) - latency = lat2; - } - fprintf(f, "lat %s ", sprint_usecs(tc_core_tick2usec(latency), b1)); - - return 0; -} - -struct qdisc_util tbf_qdisc_util = { - .id = "tbf", - .parse_qopt = tbf_parse_opt, - .print_qopt = tbf_print_opt, -}; - diff --git a/tc/tc.c b/tc/tc.c deleted file mode 100644 index fa36ee0..0000000 --- a/tc/tc.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * tc.c "tc" utility frontend. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - * Fixes: - * - * Petri Mattila <petri@prihateam.fi> 990308: wrong memset's resulted in faults - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <dlfcn.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <errno.h> - -#include "SNAPSHOT.h" -#include "utils.h" -#include "tc_util.h" -#include "tc_common.h" - -int show_stats = 0; -int show_details = 0; -int show_raw = 0; -int resolve_hosts = 0; -int use_iec = 0; -int force = 0; -struct rtnl_handle rth; - -static void *BODY = NULL; /* cached handle dlopen(NULL) */ -static struct qdisc_util * qdisc_list; -static struct filter_util * filter_list; - -static int print_noqopt(struct qdisc_util *qu, FILE *f, - struct rtattr *opt) -{ - if (opt && RTA_PAYLOAD(opt)) - fprintf(f, "[Unknown qdisc, optlen=%u] ", - (unsigned) RTA_PAYLOAD(opt)); - return 0; -} - -static int parse_noqopt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) -{ - if (argc) { - fprintf(stderr, "Unknown qdisc \"%s\", hence option \"%s\" is unparsable\n", qu->id, *argv); - return -1; - } - return 0; -} - -static int print_nofopt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 fhandle) -{ - if (opt && RTA_PAYLOAD(opt)) - fprintf(f, "fh %08x [Unknown filter, optlen=%u] ", - fhandle, (unsigned) RTA_PAYLOAD(opt)); - else if (fhandle) - fprintf(f, "fh %08x ", fhandle); - return 0; -} - -static int parse_nofopt(struct filter_util *qu, char *fhandle, int argc, char **argv, struct nlmsghdr *n) -{ - __u32 handle; - - if (argc) { - fprintf(stderr, "Unknown filter \"%s\", hence option \"%s\" is unparsable\n", qu->id, *argv); - return -1; - } - if (fhandle) { - struct tcmsg *t = NLMSG_DATA(n); - if (get_u32(&handle, fhandle, 16)) { - fprintf(stderr, "Unparsable filter ID \"%s\"\n", fhandle); - return -1; - } - t->tcm_handle = handle; - } - return 0; -} - -struct qdisc_util *get_qdisc_kind(const char *str) -{ - void *dlh; - char buf[256]; - struct qdisc_util *q; - - for (q = qdisc_list; q; q = q->next) - if (strcmp(q->id, str) == 0) - return q; - - snprintf(buf, sizeof(buf), "/usr/lib/tc/q_%s.so", str); - dlh = dlopen(buf, RTLD_LAZY); - if (!dlh) { - /* look in current binary, only open once */ - dlh = BODY; - if (dlh == NULL) { - dlh = BODY = dlopen(NULL, RTLD_LAZY); - if (dlh == NULL) - goto noexist; - } - } - - snprintf(buf, sizeof(buf), "%s_qdisc_util", str); - q = dlsym(dlh, buf); - if (q == NULL) - goto noexist; - -reg: - q->next = qdisc_list; - qdisc_list = q; - return q; - -noexist: - q = malloc(sizeof(*q)); - if (q) { - - memset(q, 0, sizeof(*q)); - q->id = strcpy(malloc(strlen(str)+1), str); - q->parse_qopt = parse_noqopt; - q->print_qopt = print_noqopt; - goto reg; - } - return q; -} - - -struct filter_util *get_filter_kind(const char *str) -{ - void *dlh; - char buf[256]; - struct filter_util *q; - - for (q = filter_list; q; q = q->next) - if (strcmp(q->id, str) == 0) - return q; - - snprintf(buf, sizeof(buf), "/usr/lib/tc/f_%s.so", str); - dlh = dlopen(buf, RTLD_LAZY); - if (dlh == NULL) { - dlh = BODY; - if (dlh == NULL) { - dlh = BODY = dlopen(NULL, RTLD_LAZY); - if (dlh == NULL) - goto noexist; - } - } - - snprintf(buf, sizeof(buf), "%s_filter_util", str); - q = dlsym(dlh, buf); - if (q == NULL) - goto noexist; - -reg: - q->next = filter_list; - filter_list = q; - return q; -noexist: - q = malloc(sizeof(*q)); - if (q) { - memset(q, 0, sizeof(*q)); - strncpy(q->id, str, 15); - q->parse_fopt = parse_nofopt; - q->print_fopt = print_nofopt; - goto reg; - } - return q; -} - -static void usage(void) -{ - fprintf(stderr, "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n" - " tc [-force] -batch file\n" - "where OBJECT := { qdisc | class | filter | action }\n" - " OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -b[atch] [file] }\n"); -} - -static int do_cmd(int argc, char **argv) -{ - if (matches(*argv, "qdisc") == 0) - return do_qdisc(argc-1, argv+1); - - if (matches(*argv, "class") == 0) - return do_class(argc-1, argv+1); - - if (matches(*argv, "filter") == 0) - return do_filter(argc-1, argv+1); - - if (matches(*argv, "actions") == 0) - return do_action(argc-1, argv+1); - - if (matches(*argv, "help") == 0) { - usage(); - return 0; - } - - fprintf(stderr, "Object \"%s\" is unknown, try \"tc help\".\n", - *argv); - return -1; -} - -static int batch(const char *name) -{ - char *line = NULL; - size_t len = 0; - int ret = 0; - - if (name && strcmp(name, "-") != 0) { - if (freopen(name, "r", stdin) == NULL) { - fprintf(stderr, "Cannot open file \"%s\" for reading: %s=n", - name, strerror(errno)); - return -1; - } - } - - tc_core_init(); - - if (rtnl_open(&rth, 0) < 0) { - fprintf(stderr, "Cannot open rtnetlink\n"); - return -1; - } - - cmdlineno = 0; - while (getcmdline(&line, &len, stdin) != -1) { - char *largv[100]; - int largc; - - largc = makeargs(line, largv, 100); - if (largc == 0) - continue; /* blank line */ - - if (do_cmd(largc, largv)) { - fprintf(stderr, "Command failed %s:%d\n", name, cmdlineno); - ret = 1; - if (!force) - break; - } - } - if (line) - free(line); - - rtnl_close(&rth); - return ret; -} - - -int main(int argc, char **argv) -{ - int ret; - int do_batching = 0; - char *batchfile = NULL; - - while (argc > 1) { - if (argv[1][0] != '-') - break; - if (matches(argv[1], "-stats") == 0 || - matches(argv[1], "-statistics") == 0) { - ++show_stats; - } else if (matches(argv[1], "-details") == 0) { - ++show_details; - } else if (matches(argv[1], "-raw") == 0) { - ++show_raw; - } else if (matches(argv[1], "-Version") == 0) { - printf("tc utility, iproute2-ss%s\n", SNAPSHOT); - return 0; - } else if (matches(argv[1], "-iec") == 0) { - ++use_iec; - } else if (matches(argv[1], "-help") == 0) { - usage(); - return 0; - } else if (matches(argv[1], "-force") == 0) { - ++force; - } else if (matches(argv[1], "-batch") == 0) { - do_batching = 1; - if (argc > 2) - batchfile = argv[2]; - argc--; argv++; - } else { - fprintf(stderr, "Option \"%s\" is unknown, try \"tc -help\".\n", argv[1]); - return -1; - } - argc--; argv++; - } - - if (do_batching) - return batch(batchfile); - - if (argc <= 1) { - usage(); - return 0; - } - - tc_core_init(); - if (rtnl_open(&rth, 0) < 0) { - fprintf(stderr, "Cannot open rtnetlink\n"); - exit(1); - } - - ret = do_cmd(argc-1, argv+1); - rtnl_close(&rth); - - return ret; -} diff --git a/tc/tc_cbq.c b/tc/tc_cbq.c deleted file mode 100644 index 0abcc9d..0000000 --- a/tc/tc_cbq.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * tc_cbq.c CBQ maintanance routines. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <math.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "tc_core.h" -#include "tc_cbq.h" - -unsigned tc_cbq_calc_maxidle(unsigned bndw, unsigned rate, unsigned avpkt, - int ewma_log, unsigned maxburst) -{ - double maxidle; - double g = 1.0 - 1.0/(1<<ewma_log); - double xmt = (double)avpkt/bndw; - - maxidle = xmt*(1-g); - if (bndw != rate && maxburst) { - double vxmt = (double)avpkt/rate - xmt; - vxmt *= (pow(g, -(double)maxburst) - 1); - if (vxmt > maxidle) - maxidle = vxmt; - } - return tc_core_usec2tick(maxidle*(1<<ewma_log)*1000000); -} - -unsigned tc_cbq_calc_offtime(unsigned bndw, unsigned rate, unsigned avpkt, - int ewma_log, unsigned minburst) -{ - double g = 1.0 - 1.0/(1<<ewma_log); - double offtime = (double)avpkt/rate - (double)avpkt/bndw; - - if (minburst == 0) - return 0; - if (minburst == 1) - offtime *= pow(g, -(double)minburst) - 1; - else - offtime *= 1 + (pow(g, -(double)(minburst-1)) - 1)/(1-g); - return tc_core_usec2tick(offtime*1000000); -} diff --git a/tc/tc_cbq.h b/tc/tc_cbq.h deleted file mode 100644 index 8f95649..0000000 --- a/tc/tc_cbq.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _TC_CBQ_H_ -#define _TC_CBQ_H_ 1 - -unsigned tc_cbq_calc_maxidle(unsigned bndw, unsigned rate, unsigned avpkt, - int ewma_log, unsigned maxburst); -unsigned tc_cbq_calc_offtime(unsigned bndw, unsigned rate, unsigned avpkt, - int ewma_log, unsigned minburst); - -#endif diff --git a/tc/tc_class.c b/tc/tc_class.c deleted file mode 100644 index 894caa1..0000000 --- a/tc/tc_class.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * tc_class.c "tc class". - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <math.h> - -#include "utils.h" -#include "tc_util.h" -#include "tc_common.h" - -static void usage(void); - -static void usage(void) -{ - fprintf(stderr, "Usage: tc class [ add | del | change | get ] dev STRING\n"); - fprintf(stderr, " [ classid CLASSID ] [ root | parent CLASSID ]\n"); - fprintf(stderr, " [ [ QDISC_KIND ] [ help | OPTIONS ] ]\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " tc class show [ dev STRING ] [ root | parent CLASSID ]\n"); - fprintf(stderr, "Where:\n"); - fprintf(stderr, "QDISC_KIND := { prio | cbq | etc. }\n"); - fprintf(stderr, "OPTIONS := ... try tc class add <desired QDISC_KIND> help\n"); - return; -} - -int tc_class_modify(int cmd, unsigned flags, int argc, char **argv) -{ - struct { - struct nlmsghdr n; - struct tcmsg t; - char buf[4096]; - } req; - struct qdisc_util *q = NULL; - struct tc_estimator est; - char d[16]; - char k[16]; - - memset(&req, 0, sizeof(req)); - memset(&est, 0, sizeof(est)); - memset(d, 0, sizeof(d)); - memset(k, 0, sizeof(k)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|flags; - req.n.nlmsg_type = cmd; - req.t.tcm_family = AF_UNSPEC; - - while (argc > 0) { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - if (d[0]) - duparg("dev", *argv); - strncpy(d, *argv, sizeof(d)-1); - } else if (strcmp(*argv, "classid") == 0) { - __u32 handle; - NEXT_ARG(); - if (req.t.tcm_handle) - duparg("classid", *argv); - if (get_tc_classid(&handle, *argv)) - invarg(*argv, "invalid class ID"); - req.t.tcm_handle = handle; - } else if (strcmp(*argv, "handle") == 0) { - fprintf(stderr, "Error: try \"classid\" instead of \"handle\"\n"); - return -1; - } else if (strcmp(*argv, "root") == 0) { - if (req.t.tcm_parent) { - fprintf(stderr, "Error: \"root\" is duplicate parent ID.\n"); - return -1; - } - req.t.tcm_parent = TC_H_ROOT; - } else if (strcmp(*argv, "parent") == 0) { - __u32 handle; - NEXT_ARG(); - if (req.t.tcm_parent) - duparg("parent", *argv); - if (get_tc_classid(&handle, *argv)) - invarg(*argv, "invalid parent ID"); - req.t.tcm_parent = handle; - } else if (matches(*argv, "estimator") == 0) { - if (parse_estimator(&argc, &argv, &est)) - return -1; - } else if (matches(*argv, "help") == 0) { - usage(); - } else { - strncpy(k, *argv, sizeof(k)-1); - - q = get_qdisc_kind(k); - argc--; argv++; - break; - } - argc--; argv++; - } - - if (k[0]) - addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1); - if (est.ewma_log) - addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est)); - - if (q) { - if (q->parse_copt == NULL) { - fprintf(stderr, "Error: Qdisc \"%s\" is classless.\n", k); - return 1; - } - if (q->parse_copt(q, argc, argv, &req.n)) - return 1; - } else { - if (argc) { - if (matches(*argv, "help") == 0) - usage(); - fprintf(stderr, "Garbage instead of arguments \"%s ...\". Try \"tc class help\".", *argv); - return -1; - } - } - - if (d[0]) { - ll_init_map(&rth); - - if ((req.t.tcm_ifindex = ll_name_to_index(d)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return 1; - } - } - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - return 2; - - return 0; -} - -int filter_ifindex; -__u32 filter_qdisc; - -static int print_class(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg) -{ - FILE *fp = (FILE*)arg; - struct tcmsg *t = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr * tb[TCA_MAX+1]; - struct qdisc_util *q; - char abuf[256]; - - if (n->nlmsg_type != RTM_NEWTCLASS && n->nlmsg_type != RTM_DELTCLASS) { - fprintf(stderr, "Not a class\n"); - return 0; - } - len -= NLMSG_LENGTH(sizeof(*t)); - if (len < 0) { - fprintf(stderr, "Wrong len %d\n", len); - return -1; - } - if (filter_qdisc && TC_H_MAJ(t->tcm_handle^filter_qdisc)) - return 0; - - memset(tb, 0, sizeof(tb)); - parse_rtattr(tb, TCA_MAX, TCA_RTA(t), len); - - if (tb[TCA_KIND] == NULL) { - fprintf(stderr, "print_class: NULL kind\n"); - return -1; - } - - if (n->nlmsg_type == RTM_DELTCLASS) - fprintf(fp, "deleted "); - - abuf[0] = 0; - if (t->tcm_handle) { - if (filter_qdisc) - print_tc_classid(abuf, sizeof(abuf), TC_H_MIN(t->tcm_handle)); - else - print_tc_classid(abuf, sizeof(abuf), t->tcm_handle); - } - fprintf(fp, "class %s %s ", (char*)RTA_DATA(tb[TCA_KIND]), abuf); - - if (filter_ifindex == 0) - fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex)); - - if (t->tcm_parent == TC_H_ROOT) - fprintf(fp, "root "); - else { - if (filter_qdisc) - print_tc_classid(abuf, sizeof(abuf), TC_H_MIN(t->tcm_parent)); - else - print_tc_classid(abuf, sizeof(abuf), t->tcm_parent); - fprintf(fp, "parent %s ", abuf); - } - if (t->tcm_info) - fprintf(fp, "leaf %x: ", t->tcm_info>>16); - q = get_qdisc_kind(RTA_DATA(tb[TCA_KIND])); - if (tb[TCA_OPTIONS]) { - if (q && q->print_copt) - q->print_copt(q, fp, tb[TCA_OPTIONS]); - else - fprintf(fp, "[cannot parse class parameters]"); - } - fprintf(fp, "\n"); - if (show_stats) { - struct rtattr *xstats = NULL; - - if (tb[TCA_STATS] || tb[TCA_STATS2]) { - print_tcstats_attr(fp, tb, " ", &xstats); - fprintf(fp, "\n"); - } - if (q && (xstats || tb[TCA_XSTATS]) && q->print_xstats) { - q->print_xstats(q, fp, xstats ? : tb[TCA_XSTATS]); - fprintf(fp, "\n"); - } - } - fflush(fp); - return 0; -} - - -int tc_class_list(int argc, char **argv) -{ - struct tcmsg t; - char d[16]; - - memset(&t, 0, sizeof(t)); - t.tcm_family = AF_UNSPEC; - memset(d, 0, sizeof(d)); - - while (argc > 0) { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - if (d[0]) - duparg("dev", *argv); - strncpy(d, *argv, sizeof(d)-1); - } else if (strcmp(*argv, "qdisc") == 0) { - NEXT_ARG(); - if (filter_qdisc) - duparg("qdisc", *argv); - if (get_qdisc_handle(&filter_qdisc, *argv)) - invarg(*argv, "invalid qdisc ID"); - } else if (strcmp(*argv, "root") == 0) { - if (t.tcm_parent) { - fprintf(stderr, "Error: \"root\" is duplicate parent ID\n"); - return -1; - } - t.tcm_parent = TC_H_ROOT; - } else if (strcmp(*argv, "parent") == 0) { - __u32 handle; - if (t.tcm_parent) - duparg("parent", *argv); - NEXT_ARG(); - if (get_tc_classid(&handle, *argv)) - invarg(*argv, "invalid parent ID"); - t.tcm_parent = handle; - } else if (matches(*argv, "help") == 0) { - usage(); - } else { - fprintf(stderr, "What is \"%s\"? Try \"tc class help\".\n", *argv); - return -1; - } - - argc--; argv++; - } - - ll_init_map(&rth); - - if (d[0]) { - if ((t.tcm_ifindex = ll_name_to_index(d)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return 1; - } - filter_ifindex = t.tcm_ifindex; - } - - if (rtnl_dump_request(&rth, RTM_GETTCLASS, &t, sizeof(t)) < 0) { - perror("Cannot send dump request"); - return 1; - } - - if (rtnl_dump_filter(&rth, print_class, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - return 1; - } - - return 0; -} - -int do_class(int argc, char **argv) -{ - if (argc < 1) - return tc_class_list(0, NULL); - if (matches(*argv, "add") == 0) - return tc_class_modify(RTM_NEWTCLASS, NLM_F_EXCL|NLM_F_CREATE, argc-1, argv+1); - if (matches(*argv, "change") == 0) - return tc_class_modify(RTM_NEWTCLASS, 0, argc-1, argv+1); - if (matches(*argv, "replace") == 0) - return tc_class_modify(RTM_NEWTCLASS, NLM_F_CREATE, argc-1, argv+1); - if (matches(*argv, "delete") == 0) - return tc_class_modify(RTM_DELTCLASS, 0, argc-1, argv+1); -#if 0 - if (matches(*argv, "get") == 0) - return tc_class_get(RTM_GETTCLASS, 0, argc-1, argv+1); -#endif - if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 - || matches(*argv, "lst") == 0) - return tc_class_list(argc-1, argv+1); - if (matches(*argv, "help") == 0) - usage(); - fprintf(stderr, "Command \"%s\" is unknown, try \"tc class help\".\n", *argv); - return -1; -} diff --git a/tc/tc_common.h b/tc/tc_common.h deleted file mode 100644 index 7e13582..0000000 --- a/tc/tc_common.h +++ /dev/null @@ -1,11 +0,0 @@ - -#define TCA_BUF_MAX (64*1024) - -extern struct rtnl_handle rth; -extern int do_qdisc(int argc, char **argv); -extern int do_class(int argc, char **argv); -extern int do_filter(int argc, char **argv); -extern int do_action(int argc, char **argv); - -struct tc_estimator; -extern int parse_estimator(int *p_argc, char ***p_argv, struct tc_estimator *est); diff --git a/tc/tc_core.c b/tc/tc_core.c deleted file mode 100644 index 07cf2fa..0000000 --- a/tc/tc_core.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * tc_core.c TC core library. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <math.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "tc_core.h" - -static __u32 t2us=1; -static __u32 us2t=1; -static double tick_in_usec = 1; - -long tc_core_usec2tick(long usec) -{ - return usec*tick_in_usec; -} - -long tc_core_tick2usec(long tick) -{ - return tick/tick_in_usec; -} - -unsigned tc_calc_xmittime(unsigned rate, unsigned size) -{ - return tc_core_usec2tick(1000000*((double)size/rate)); -} - -/* - rtab[pkt_len>>cell_log] = pkt_xmit_time - */ - -int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu, - unsigned mpu) -{ - int i; - unsigned overhead = (mpu >> 8) & 0xFF; - mpu = mpu & 0xFF; - - if (mtu == 0) - mtu = 2047; - - if (cell_log < 0) { - cell_log = 0; - while ((mtu>>cell_log) > 255) - cell_log++; - } - for (i=0; i<256; i++) { - unsigned sz = (i<<cell_log); - if (overhead) - sz += overhead; - if (sz < mpu) - sz = mpu; - rtab[i] = tc_core_usec2tick(1000000*((double)sz/bps)); - } - return cell_log; -} - -int tc_core_init() -{ - FILE *fp = fopen("/proc/net/psched", "r"); - - if (fp == NULL) - return -1; - - if (fscanf(fp, "%08x%08x", &t2us, &us2t) != 2) { - fclose(fp); - return -1; - } - fclose(fp); - tick_in_usec = (double)t2us/us2t; - return 0; -} diff --git a/tc/tc_core.h b/tc/tc_core.h deleted file mode 100644 index 1537f95..0000000 --- a/tc/tc_core.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _TC_CORE_H_ -#define _TC_CORE_H_ 1 - -#include <asm/types.h> -#include <linux/pkt_sched.h> - -long tc_core_usec2tick(long usec); -long tc_core_tick2usec(long tick); -unsigned tc_calc_xmittime(unsigned rate, unsigned size); -int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu, unsigned mpu); - -int tc_setup_estimator(unsigned A, unsigned time_const, struct tc_estimator *est); - -int tc_core_init(void); - -extern struct rtnl_handle g_rth; -extern int is_batch_mode; - -#endif diff --git a/tc/tc_estimator.c b/tc/tc_estimator.c deleted file mode 100644 index 434db0f..0000000 --- a/tc/tc_estimator.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * tc_core.c TC core library. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <math.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "tc_core.h" - -int tc_setup_estimator(unsigned A, unsigned time_const, struct tc_estimator *est) -{ - for (est->interval=0; est->interval<=5; est->interval++) { - if (A <= (1<<est->interval)*(1000000/4)) - break; - } - if (est->interval > 5) - return -1; - est->interval -= 2; - for (est->ewma_log=1; est->ewma_log<32; est->ewma_log++) { - double w = 1.0 - 1.0/(1<<est->ewma_log); - if (A/(-log(w)) > time_const) - break; - } - est->ewma_log--; - if (est->ewma_log==0 || est->ewma_log >= 31) - return -1; - return 0; -} diff --git a/tc/tc_filter.c b/tc/tc_filter.c deleted file mode 100644 index f6de840..0000000 --- a/tc/tc_filter.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * tc_filter.c "tc filter". - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <linux/if_ether.h> - -#include "rt_names.h" -#include "utils.h" -#include "tc_util.h" -#include "tc_common.h" - -static void usage(void); - -static void usage(void) -{ - fprintf(stderr, "Usage: tc filter [ add | del | change | get ] dev STRING\n"); - fprintf(stderr, " [ pref PRIO ] [ protocol PROTO ]\n"); - fprintf(stderr, " [ estimator INTERVAL TIME_CONSTANT ]\n"); - fprintf(stderr, " [ root | classid CLASSID ] [ handle FILTERID ]\n"); - fprintf(stderr, " [ [ FILTER_TYPE ] [ help | OPTIONS ] ]\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " tc filter show [ dev STRING ] [ root | parent CLASSID ]\n"); - fprintf(stderr, "Where:\n"); - fprintf(stderr, "FILTER_TYPE := { rsvp | u32 | fw | route | etc. }\n"); - fprintf(stderr, "FILTERID := ... format depends on classifier, see there\n"); - fprintf(stderr, "OPTIONS := ... try tc filter add <desired FILTER_KIND> help\n"); - return; -} - - -int tc_filter_modify(int cmd, unsigned flags, int argc, char **argv) -{ - struct { - struct nlmsghdr n; - struct tcmsg t; - char buf[MAX_MSG]; - } req; - struct filter_util *q = NULL; - __u32 prio = 0; - __u32 protocol = 0; - char *fhandle = NULL; - char d[16]; - char k[16]; - struct tc_estimator est; - - memset(&req, 0, sizeof(req)); - memset(&est, 0, sizeof(est)); - memset(d, 0, sizeof(d)); - memset(k, 0, sizeof(k)); - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|flags; - req.n.nlmsg_type = cmd; - req.t.tcm_family = AF_UNSPEC; - - while (argc > 0) { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - if (d[0]) - duparg("dev", *argv); - strncpy(d, *argv, sizeof(d)-1); - } else if (strcmp(*argv, "root") == 0) { - if (req.t.tcm_parent) { - fprintf(stderr, "Error: \"root\" is duplicate parent ID\n"); - return -1; - } - req.t.tcm_parent = TC_H_ROOT; - } else if (strcmp(*argv, "parent") == 0) { - __u32 handle; - NEXT_ARG(); - if (req.t.tcm_parent) - duparg("parent", *argv); - if (get_tc_classid(&handle, *argv)) - invarg(*argv, "Invalid parent ID"); - req.t.tcm_parent = handle; - } else if (strcmp(*argv, "handle") == 0) { - NEXT_ARG(); - if (fhandle) - duparg("handle", *argv); - fhandle = *argv; - } else if (matches(*argv, "preference") == 0 || - matches(*argv, "priority") == 0) { - NEXT_ARG(); - if (prio) - duparg("priority", *argv); - if (get_u32(&prio, *argv, 0)) - invarg(*argv, "invalid prpriority value"); - } else if (matches(*argv, "protocol") == 0) { - __u16 id; - NEXT_ARG(); - if (protocol) - duparg("protocol", *argv); - if (ll_proto_a2n(&id, *argv)) - invarg(*argv, "invalid protocol"); - protocol = id; - } else if (matches(*argv, "estimator") == 0) { - if (parse_estimator(&argc, &argv, &est) < 0) - return -1; - } else if (matches(*argv, "help") == 0) { - usage(); - } else { - strncpy(k, *argv, sizeof(k)-1); - - q = get_filter_kind(k); - argc--; argv++; - break; - } - - argc--; argv++; - } - - req.t.tcm_info = TC_H_MAKE(prio<<16, protocol); - - if (k[0]) - addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1); - - if (q) { - if (q->parse_fopt(q, fhandle, argc, argv, &req.n)) - return 1; - } else { - if (fhandle) { - fprintf(stderr, "Must specify filter type when using " - "\"handle\"\n"); - return -1; - } - if (argc) { - if (matches(*argv, "help") == 0) - usage(); - fprintf(stderr, "Garbage instead of arguments \"%s ...\". Try \"tc filter help\".\n", *argv); - return -1; - } - } - if (est.ewma_log) - addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est)); - - - if (d[0]) { - ll_init_map(&rth); - - if ((req.t.tcm_ifindex = ll_name_to_index(d)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return 1; - } - } - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) { - fprintf(stderr, "We have an error talking to the kernel\n"); - return 2; - } - - return 0; -} - -static __u32 filter_parent; -static int filter_ifindex; -static __u32 filter_prio; -static __u32 filter_protocol; - -static int print_filter(const struct sockaddr_nl *who, - struct nlmsghdr *n, - void *arg) -{ - FILE *fp = (FILE*)arg; - struct tcmsg *t = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr * tb[TCA_MAX+1]; - struct filter_util *q; - char abuf[256]; - - if (n->nlmsg_type != RTM_NEWTFILTER && n->nlmsg_type != RTM_DELTFILTER) { - fprintf(stderr, "Not a filter\n"); - return 0; - } - len -= NLMSG_LENGTH(sizeof(*t)); - if (len < 0) { - fprintf(stderr, "Wrong len %d\n", len); - return -1; - } - - memset(tb, 0, sizeof(tb)); - parse_rtattr(tb, TCA_MAX, TCA_RTA(t), len); - - if (tb[TCA_KIND] == NULL) { - fprintf(stderr, "print_filter: NULL kind\n"); - return -1; - } - - if (n->nlmsg_type == RTM_DELTFILTER) - fprintf(fp, "deleted "); - - fprintf(fp, "filter "); - if (!filter_ifindex || filter_ifindex != t->tcm_ifindex) - fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex)); - - if (!filter_parent || filter_parent != t->tcm_parent) { - if (t->tcm_parent == TC_H_ROOT) - fprintf(fp, "root "); - else { - print_tc_classid(abuf, sizeof(abuf), t->tcm_parent); - fprintf(fp, "parent %s ", abuf); - } - } - if (t->tcm_info) { - __u32 protocol = TC_H_MIN(t->tcm_info); - __u32 prio = TC_H_MAJ(t->tcm_info)>>16; - if (!filter_protocol || filter_protocol != protocol) { - if (protocol) { - SPRINT_BUF(b1); - fprintf(fp, "protocol %s ", - ll_proto_n2a(protocol, b1, sizeof(b1))); - } - } - if (!filter_prio || filter_prio != prio) { - if (prio) - fprintf(fp, "pref %u ", prio); - } - } - fprintf(fp, "%s ", (char*)RTA_DATA(tb[TCA_KIND])); - q = get_filter_kind(RTA_DATA(tb[TCA_KIND])); - if (tb[TCA_OPTIONS]) { - if (q) - q->print_fopt(q, fp, tb[TCA_OPTIONS], t->tcm_handle); - else - fprintf(fp, "[cannot parse parameters]"); - } - fprintf(fp, "\n"); - - if (show_stats && (tb[TCA_STATS] || tb[TCA_STATS2])) { - print_tcstats_attr(fp, tb, " ", NULL); - fprintf(fp, "\n"); - } - - fflush(fp); - return 0; -} - - -int tc_filter_list(int argc, char **argv) -{ - struct tcmsg t; - char d[16]; - __u32 prio = 0; - __u32 protocol = 0; - char *fhandle = NULL; - - memset(&t, 0, sizeof(t)); - t.tcm_family = AF_UNSPEC; - memset(d, 0, sizeof(d)); - - while (argc > 0) { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - if (d[0]) - duparg("dev", *argv); - strncpy(d, *argv, sizeof(d)-1); - } else if (strcmp(*argv, "root") == 0) { - if (t.tcm_parent) { - fprintf(stderr, "Error: \"root\" is duplicate parent ID\n"); - return -1; - } - filter_parent = t.tcm_parent = TC_H_ROOT; - } else if (strcmp(*argv, "parent") == 0) { - __u32 handle; - NEXT_ARG(); - if (t.tcm_parent) - duparg("parent", *argv); - if (get_tc_classid(&handle, *argv)) - invarg(*argv, "invalid parent ID"); - filter_parent = t.tcm_parent = handle; - } else if (strcmp(*argv, "handle") == 0) { - NEXT_ARG(); - if (fhandle) - duparg("handle", *argv); - fhandle = *argv; - } else if (matches(*argv, "preference") == 0 || - matches(*argv, "priority") == 0) { - NEXT_ARG(); - if (prio) - duparg("priority", *argv); - if (get_u32(&prio, *argv, 0)) - invarg(*argv, "invalid preference"); - filter_prio = prio; - } else if (matches(*argv, "protocol") == 0) { - __u16 res; - NEXT_ARG(); - if (protocol) - duparg("protocol", *argv); - if (ll_proto_a2n(&res, *argv)) - invarg(*argv, "invalid protocol"); - protocol = res; - filter_protocol = protocol; - } else if (matches(*argv, "help") == 0) { - usage(); - } else { - fprintf(stderr, " What is \"%s\"? Try \"tc filter help\"\n", *argv); - return -1; - } - - argc--; argv++; - } - - t.tcm_info = TC_H_MAKE(prio<<16, protocol); - - ll_init_map(&rth); - - if (d[0]) { - if ((t.tcm_ifindex = ll_name_to_index(d)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return 1; - } - filter_ifindex = t.tcm_ifindex; - } - - if (rtnl_dump_request(&rth, RTM_GETTFILTER, &t, sizeof(t)) < 0) { - perror("Cannot send dump request"); - return 1; - } - - if (rtnl_dump_filter(&rth, print_filter, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - return 1; - } - - return 0; -} - -int do_filter(int argc, char **argv) -{ - if (argc < 1) - return tc_filter_list(0, NULL); - if (matches(*argv, "add") == 0) - return tc_filter_modify(RTM_NEWTFILTER, NLM_F_EXCL|NLM_F_CREATE, argc-1, argv+1); - if (matches(*argv, "change") == 0) - return tc_filter_modify(RTM_NEWTFILTER, 0, argc-1, argv+1); - if (matches(*argv, "replace") == 0) - return tc_filter_modify(RTM_NEWTFILTER, NLM_F_CREATE, argc-1, argv+1); - if (matches(*argv, "delete") == 0) - return tc_filter_modify(RTM_DELTFILTER, 0, argc-1, argv+1); -#if 0 - if (matches(*argv, "get") == 0) - return tc_filter_get(RTM_GETTFILTER, 0, argc-1, argv+1); -#endif - if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 - || matches(*argv, "lst") == 0) - return tc_filter_list(argc-1, argv+1); - if (matches(*argv, "help") == 0) - usage(); - fprintf(stderr, "Command \"%s\" is unknown, try \"tc filter help\".\n", *argv); - return -1; -} - diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c deleted file mode 100644 index e9174ab..0000000 --- a/tc/tc_qdisc.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * tc_qdisc.c "tc qdisc". - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * J Hadi Salim: Extension to ingress - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <math.h> - -#include "utils.h" -#include "tc_util.h" -#include "tc_common.h" - -static int usage(void); - -static int usage(void) -{ - fprintf(stderr, "Usage: tc qdisc [ add | del | replace | change | get ] dev STRING\n"); - fprintf(stderr, " [ handle QHANDLE ] [ root | ingress | parent CLASSID ]\n"); - fprintf(stderr, " [ estimator INTERVAL TIME_CONSTANT ]\n"); - fprintf(stderr, " [ [ QDISC_KIND ] [ help | OPTIONS ] ]\n"); - fprintf(stderr, "\n"); - fprintf(stderr, " tc qdisc show [ dev STRING ] [ingress]\n"); - fprintf(stderr, "Where:\n"); - fprintf(stderr, "QDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. }\n"); - fprintf(stderr, "OPTIONS := ... try tc qdisc add <desired QDISC_KIND> help\n"); - return -1; -} - -int tc_qdisc_modify(int cmd, unsigned flags, int argc, char **argv) -{ - struct qdisc_util *q = NULL; - struct tc_estimator est; - char d[16]; - char k[16]; - struct { - struct nlmsghdr n; - struct tcmsg t; - char buf[TCA_BUF_MAX]; - } req; - - memset(&req, 0, sizeof(req)); - memset(&est, 0, sizeof(est)); - memset(&d, 0, sizeof(d)); - memset(&k, 0, sizeof(k)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|flags; - req.n.nlmsg_type = cmd; - req.t.tcm_family = AF_UNSPEC; - - while (argc > 0) { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - if (d[0]) - duparg("dev", *argv); - strncpy(d, *argv, sizeof(d)-1); - } else if (strcmp(*argv, "handle") == 0) { - __u32 handle; - if (req.t.tcm_handle) - duparg("handle", *argv); - NEXT_ARG(); - if (get_qdisc_handle(&handle, *argv)) - invarg(*argv, "invalid qdisc ID"); - req.t.tcm_handle = handle; - } else if (strcmp(*argv, "root") == 0) { - if (req.t.tcm_parent) { - fprintf(stderr, "Error: \"root\" is duplicate parent ID\n"); - return -1; - } - req.t.tcm_parent = TC_H_ROOT; -#ifdef TC_H_INGRESS - } else if (strcmp(*argv, "ingress") == 0) { - if (req.t.tcm_parent) { - fprintf(stderr, "Error: \"ingress\" is a duplicate parent ID\n"); - return -1; - } - req.t.tcm_parent = TC_H_INGRESS; - strncpy(k, "ingress", sizeof(k)-1); - q = get_qdisc_kind(k); - req.t.tcm_handle = 0xffff0000; - - argc--; argv++; - break; -#endif - } else if (strcmp(*argv, "parent") == 0) { - __u32 handle; - NEXT_ARG(); - if (req.t.tcm_parent) - duparg("parent", *argv); - if (get_tc_classid(&handle, *argv)) - invarg(*argv, "invalid parent ID"); - req.t.tcm_parent = handle; - } else if (matches(*argv, "estimator") == 0) { - if (parse_estimator(&argc, &argv, &est)) - return -1; - } else if (matches(*argv, "help") == 0) { - usage(); - } else { - strncpy(k, *argv, sizeof(k)-1); - - q = get_qdisc_kind(k); - argc--; argv++; - break; - } - argc--; argv++; - } - - if (k[0]) - addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1); - if (est.ewma_log) - addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est)); - - if (q) { - if (!q->parse_qopt) { - fprintf(stderr, "qdisc '%s' does not support option parsing\n", k); - return -1; - } - if (q->parse_qopt(q, argc, argv, &req.n)) - return 1; - } else { - if (argc) { - if (matches(*argv, "help") == 0) - usage(); - - fprintf(stderr, "Garbage instead of arguments \"%s ...\". Try \"tc qdisc help\".\n", *argv); - return -1; - } - } - - if (d[0]) { - int idx; - - ll_init_map(&rth); - - if ((idx = ll_name_to_index(d)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return 1; - } - req.t.tcm_ifindex = idx; - } - - if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) - return 2; - - return 0; -} - -static int filter_ifindex; - -static int print_qdisc(const struct sockaddr_nl *who, - struct nlmsghdr *n, - void *arg) -{ - FILE *fp = (FILE*)arg; - struct tcmsg *t = NLMSG_DATA(n); - int len = n->nlmsg_len; - struct rtattr * tb[TCA_MAX+1]; - struct qdisc_util *q; - char abuf[256]; - - if (n->nlmsg_type != RTM_NEWQDISC && n->nlmsg_type != RTM_DELQDISC) { - fprintf(stderr, "Not a qdisc\n"); - return 0; - } - len -= NLMSG_LENGTH(sizeof(*t)); - if (len < 0) { - fprintf(stderr, "Wrong len %d\n", len); - return -1; - } - - if (filter_ifindex && filter_ifindex != t->tcm_ifindex) - return 0; - - memset(tb, 0, sizeof(tb)); - parse_rtattr(tb, TCA_MAX, TCA_RTA(t), len); - - if (tb[TCA_KIND] == NULL) { - fprintf(stderr, "print_qdisc: NULL kind\n"); - return -1; - } - - if (n->nlmsg_type == RTM_DELQDISC) - fprintf(fp, "deleted "); - - fprintf(fp, "qdisc %s %x: ", (char*)RTA_DATA(tb[TCA_KIND]), t->tcm_handle>>16); - if (filter_ifindex == 0) - fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex)); - if (t->tcm_parent == TC_H_ROOT) - fprintf(fp, "root "); - else if (t->tcm_parent) { - print_tc_classid(abuf, sizeof(abuf), t->tcm_parent); - fprintf(fp, "parent %s ", abuf); - } - if (t->tcm_info != 1) { - fprintf(fp, "refcnt %d ", t->tcm_info); - } - /* pfifo_fast is generic enough to warrant the hardcoding --JHS */ - - if (0 == strcmp("pfifo_fast", RTA_DATA(tb[TCA_KIND]))) - q = get_qdisc_kind("prio"); - else - q = get_qdisc_kind(RTA_DATA(tb[TCA_KIND])); - - if (tb[TCA_OPTIONS]) { - if (q) - q->print_qopt(q, fp, tb[TCA_OPTIONS]); - else - fprintf(fp, "[cannot parse qdisc parameters]"); - } - fprintf(fp, "\n"); - if (show_stats) { - struct rtattr *xstats = NULL; - - if (tb[TCA_STATS] || tb[TCA_STATS2] || tb[TCA_XSTATS]) { - print_tcstats_attr(fp, tb, " ", &xstats); - fprintf(fp, "\n"); - } - - if (q && xstats && q->print_xstats) { - q->print_xstats(q, fp, xstats); - fprintf(fp, "\n"); - } - } - fflush(fp); - return 0; -} - - -int tc_qdisc_list(int argc, char **argv) -{ - struct tcmsg t; - char d[16]; - - memset(&t, 0, sizeof(t)); - t.tcm_family = AF_UNSPEC; - memset(&d, 0, sizeof(d)); - - while (argc > 0) { - if (strcmp(*argv, "dev") == 0) { - NEXT_ARG(); - strncpy(d, *argv, sizeof(d)-1); -#ifdef TC_H_INGRESS - } else if (strcmp(*argv, "ingress") == 0) { - if (t.tcm_parent) { - fprintf(stderr, "Duplicate parent ID\n"); - usage(); - } - t.tcm_parent = TC_H_INGRESS; -#endif - } else if (matches(*argv, "help") == 0) { - usage(); - } else { - fprintf(stderr, "What is \"%s\"? Try \"tc qdisc help\".\n", *argv); - return -1; - } - - argc--; argv++; - } - - ll_init_map(&rth); - - if (d[0]) { - if ((t.tcm_ifindex = ll_name_to_index(d)) == 0) { - fprintf(stderr, "Cannot find device \"%s\"\n", d); - return 1; - } - filter_ifindex = t.tcm_ifindex; - } - - if (rtnl_dump_request(&rth, RTM_GETQDISC, &t, sizeof(t)) < 0) { - perror("Cannot send dump request"); - return 1; - } - - if (rtnl_dump_filter(&rth, print_qdisc, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - return 1; - } - - return 0; -} - -int do_qdisc(int argc, char **argv) -{ - if (argc < 1) - return tc_qdisc_list(0, NULL); - if (matches(*argv, "add") == 0) - return tc_qdisc_modify(RTM_NEWQDISC, NLM_F_EXCL|NLM_F_CREATE, argc-1, argv+1); - if (matches(*argv, "change") == 0) - return tc_qdisc_modify(RTM_NEWQDISC, 0, argc-1, argv+1); - if (matches(*argv, "replace") == 0) - return tc_qdisc_modify(RTM_NEWQDISC, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1); - if (matches(*argv, "link") == 0) - return tc_qdisc_modify(RTM_NEWQDISC, NLM_F_REPLACE, argc-1, argv+1); - if (matches(*argv, "delete") == 0) - return tc_qdisc_modify(RTM_DELQDISC, 0, argc-1, argv+1); -#if 0 - if (matches(*argv, "get") == 0) - return tc_qdisc_get(RTM_GETQDISC, 0, argc-1, argv+1); -#endif - if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 - || matches(*argv, "lst") == 0) - return tc_qdisc_list(argc-1, argv+1); - if (matches(*argv, "help") == 0) - usage(); - fprintf(stderr, "Command \"%s\" is unknown, try \"tc qdisc help\".\n", *argv); - return -1; -} diff --git a/tc/tc_red.c b/tc/tc_red.c deleted file mode 100644 index 385e7af..0000000 --- a/tc/tc_red.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * tc_red.c RED maintanance routines. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <math.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include "tc_core.h" -#include "tc_red.h" - -/* - Plog = log(prob/(qmax - qmin)) - */ -int tc_red_eval_P(unsigned qmin, unsigned qmax, double prob) -{ - int i = qmax - qmin; - - if (i <= 0) - return -1; - - prob /= i; - - for (i=0; i<32; i++) { - if (prob > 1.0) - break; - prob *= 2; - } - if (i>=32) - return -1; - return i; -} - -/* - burst + 1 - qmin/avpkt < (1-(1-W)^burst)/W - */ - -int tc_red_eval_ewma(unsigned qmin, unsigned burst, unsigned avpkt) -{ - int wlog = 1; - double W = 0.5; - double a = (double)burst + 1 - (double)qmin/avpkt; - - if (a < 1.0) - return -1; - for (wlog=1; wlog<32; wlog++, W /= 2) { - if (a <= (1 - pow(1-W, burst))/W) - return wlog; - } - return -1; -} - -/* - Stab[t>>Scell_log] = -log(1-W) * t/xmit_time - */ - -int tc_red_eval_idle_damping(int Wlog, unsigned avpkt, unsigned bps, __u8 *sbuf) -{ - double xmit_time = tc_core_usec2tick(1000000*(double)avpkt/bps); - double lW = -log(1.0 - 1.0/(1<<Wlog))/xmit_time; - double maxtime = 31/lW; - int clog; - int i; - double tmp; - - tmp = maxtime; - for (clog=0; clog<32; clog++) { - if (maxtime/(1<<clog) < 512) - break; - } - if (clog >= 32) - return -1; - - sbuf[0] = 0; - for (i=1; i<255; i++) { - sbuf[i] = (i<<clog)*lW; - if (sbuf[i] > 31) - sbuf[i] = 31; - } - sbuf[255] = 31; - return clog; -} diff --git a/tc/tc_red.h b/tc/tc_red.h deleted file mode 100644 index 6f6b09e..0000000 --- a/tc/tc_red.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _TC_RED_H_ -#define _TC_RED_H_ 1 - -extern int tc_red_eval_P(unsigned qmin, unsigned qmax, double prob); -extern int tc_red_eval_ewma(unsigned qmin, unsigned burst, unsigned avpkt); -extern int tc_red_eval_idle_damping(int wlog, unsigned avpkt, unsigned bandwidth, __u8 *sbuf); - -#endif diff --git a/tc/tc_util.c b/tc/tc_util.c deleted file mode 100644 index 9cde144..0000000 --- a/tc/tc_util.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * tc_util.c Misc TC utility functions. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> -#include <math.h> - -#include "utils.h" -#include "tc_util.h" - -int get_qdisc_handle(__u32 *h, const char *str) -{ - __u32 maj; - char *p; - - maj = TC_H_UNSPEC; - if (strcmp(str, "none") == 0) - goto ok; - maj = strtoul(str, &p, 16); - if (p == str) - return -1; - maj <<= 16; - if (*p != ':' && *p!=0) - return -1; -ok: - *h = maj; - return 0; -} - -int get_tc_classid(__u32 *h, const char *str) -{ - __u32 maj, min; - char *p; - - maj = TC_H_ROOT; - if (strcmp(str, "root") == 0) - goto ok; - maj = TC_H_UNSPEC; - if (strcmp(str, "none") == 0) - goto ok; - maj = strtoul(str, &p, 16); - if (p == str) { - maj = 0; - if (*p != ':') - return -1; - } - if (*p == ':') { - if (maj >= (1<<16)) - return -1; - maj <<= 16; - str = p+1; - min = strtoul(str, &p, 16); - if (*p != 0) - return -1; - if (min >= (1<<16)) - return -1; - maj |= min; - } else if (*p != 0) - return -1; - -ok: - *h = maj; - return 0; -} - -int print_tc_classid(char *buf, int len, __u32 h) -{ - if (h == TC_H_ROOT) - sprintf(buf, "root"); - else if (h == TC_H_UNSPEC) - snprintf(buf, len, "none"); - else if (TC_H_MAJ(h) == 0) - snprintf(buf, len, ":%x", TC_H_MIN(h)); - else if (TC_H_MIN(h) == 0) - snprintf(buf, len, "%x:", TC_H_MAJ(h)>>16); - else - snprintf(buf, len, "%x:%x", TC_H_MAJ(h)>>16, TC_H_MIN(h)); - return 0; -} - -char * sprint_tc_classid(__u32 h, char *buf) -{ - if (print_tc_classid(buf, SPRINT_BSIZE-1, h)) - strcpy(buf, "???"); - return buf; -} - -/* See http://physics.nist.gov/cuu/Units/binary.html */ -static const struct rate_suffix { - const char *name; - double scale; -} suffixes[] = { - { "bit", 1. }, - { "Kibit", 1024. }, - { "kbit", 1000. }, - { "mibit", 1024.*1024. }, - { "mbit", 1000000. }, - { "gibit", 1024.*1024.*1024. }, - { "gbit", 1000000000. }, - { "tibit", 1024.*1024.*1024.*1024. }, - { "tbit", 1000000000000. }, - { "Bps", 8. }, - { "KiBps", 8.*1024. }, - { "KBps", 8000. }, - { "MiBps", 8.*1024*1024. }, - { "MBps", 8000000. }, - { "GiBps", 8.*1024.*1024.*1024. }, - { "GBps", 8000000000. }, - { "TiBps", 8.*1024.*1024.*1024.*1024. }, - { "TBps", 8000000000000. }, - { NULL } -}; - - -int get_rate(unsigned *rate, const char *str) -{ - char *p; - double bps = strtod(str, &p); - const struct rate_suffix *s; - - if (p == str) - return -1; - - if (*p == '\0') { - *rate = bps / 8.; /* assume bytes/sec */ - return 0; - } - - for (s = suffixes; s->name; ++s) { - if (strcasecmp(s->name, p) == 0) { - *rate = (bps * s->scale) / 8.; - return 0; - } - } - - return -1; -} - -int get_rate_and_cell(unsigned *rate, int *cell_log, char *str) -{ - char * slash = strchr(str, '/'); - - if (slash) - *slash = 0; - - if (get_rate(rate, str)) - return -1; - - if (slash) { - int cell; - int i; - - if (get_integer(&cell, slash+1, 0)) - return -1; - *slash = '/'; - - for (i=0; i<32; i++) { - if ((1<<i) == cell) { - *cell_log = i; - return 0; - } - } - return -1; - } - return 0; -} - -void print_rate(char *buf, int len, __u32 rate) -{ - double tmp = (double)rate*8; - extern int use_iec; - - if (use_iec) { - if (tmp >= 1000.0*1024.0*1024.0) - snprintf(buf, len, "%.0fMibit", tmp/1024.0*1024.0); - else if (tmp >= 1000.0*1024) - snprintf(buf, len, "%.0fKibit", tmp/1024); - else - snprintf(buf, len, "%.0fbit", tmp); - } else { - if (tmp >= 1000.0*1000000.0) - snprintf(buf, len, "%.0fMbit", tmp/1000000.0); - else if (tmp >= 1000.0 * 1000.0) - snprintf(buf, len, "%.0fKbit", tmp/1000.0); - else - snprintf(buf, len, "%.0fbit", tmp); - } -} - -char * sprint_rate(__u32 rate, char *buf) -{ - print_rate(buf, SPRINT_BSIZE-1, rate); - return buf; -} - -int get_usecs(unsigned *usecs, const char *str) -{ - double t; - char *p; - - t = strtod(str, &p); - if (p == str) - return -1; - - if (*p) { - if (strcasecmp(p, "s") == 0 || strcasecmp(p, "sec")==0 || - strcasecmp(p, "secs")==0) - t *= 1000000; - else if (strcasecmp(p, "ms") == 0 || strcasecmp(p, "msec")==0 || - strcasecmp(p, "msecs") == 0) - t *= 1000; - else if (strcasecmp(p, "us") == 0 || strcasecmp(p, "usec")==0 || - strcasecmp(p, "usecs") == 0) - t *= 1; - else - return -1; - } - - *usecs = t; - return 0; -} - - -void print_usecs(char *buf, int len, __u32 usec) -{ - double tmp = usec; - - if (tmp >= 1000000) - snprintf(buf, len, "%.1fs", tmp/1000000); - else if (tmp >= 1000) - snprintf(buf, len, "%.1fms", tmp/1000); - else - snprintf(buf, len, "%uus", usec); -} - -char * sprint_usecs(__u32 usecs, char *buf) -{ - print_usecs(buf, SPRINT_BSIZE-1, usecs); - return buf; -} - -int get_size(unsigned *size, const char *str) -{ - double sz; - char *p; - - sz = strtod(str, &p); - if (p == str) - return -1; - - if (*p) { - if (strcasecmp(p, "kb") == 0 || strcasecmp(p, "k")==0) - sz *= 1024; - else if (strcasecmp(p, "gb") == 0 || strcasecmp(p, "g")==0) - sz *= 1024*1024*1024; - else if (strcasecmp(p, "gbit") == 0) - sz *= 1024*1024*1024/8; - else if (strcasecmp(p, "mb") == 0 || strcasecmp(p, "m")==0) - sz *= 1024*1024; - else if (strcasecmp(p, "mbit") == 0) - sz *= 1024*1024/8; - else if (strcasecmp(p, "kbit") == 0) - sz *= 1024/8; - else if (strcasecmp(p, "b") != 0) - return -1; - } - - *size = sz; - return 0; -} - -int get_size_and_cell(unsigned *size, int *cell_log, char *str) -{ - char * slash = strchr(str, '/'); - - if (slash) - *slash = 0; - - if (get_size(size, str)) - return -1; - - if (slash) { - int cell; - int i; - - if (get_integer(&cell, slash+1, 0)) - return -1; - *slash = '/'; - - for (i=0; i<32; i++) { - if ((1<<i) == cell) { - *cell_log = i; - return 0; - } - } - return -1; - } - return 0; -} - -void print_size(char *buf, int len, __u32 sz) -{ - double tmp = sz; - - if (sz >= 1024*1024 && fabs(1024*1024*rint(tmp/(1024*1024)) - sz) < 1024) - snprintf(buf, len, "%gMb", rint(tmp/(1024*1024))); - else if (sz >= 1024 && fabs(1024*rint(tmp/1024) - sz) < 16) - snprintf(buf, len, "%gKb", rint(tmp/1024)); - else - snprintf(buf, len, "%ub", sz); -} - -char * sprint_size(__u32 size, char *buf) -{ - print_size(buf, SPRINT_BSIZE-1, size); - return buf; -} - -static const double max_percent_value = 0xffffffff; - -int get_percent(__u32 *percent, const char *str) -{ - char *p; - double per = strtod(str, &p) / 100.; - - if (per > 1. || per < 0) - return -1; - if (*p && strcmp(p, "%")) - return -1; - - *percent = (unsigned) rint(per * max_percent_value); - return 0; -} - -void print_percent(char *buf, int len, __u32 per) -{ - snprintf(buf, len, "%g%%", 100. * (double) per / max_percent_value); -} - -char * sprint_percent(__u32 per, char *buf) -{ - print_percent(buf, SPRINT_BSIZE-1, per); - return buf; -} - -void print_qdisc_handle(char *buf, int len, __u32 h) -{ - snprintf(buf, len, "%x:", TC_H_MAJ(h)>>16); -} - -char * sprint_qdisc_handle(__u32 h, char *buf) -{ - print_qdisc_handle(buf, SPRINT_BSIZE-1, h); - return buf; -} - -char * action_n2a(int action, char *buf, int len) -{ - switch (action) { - case -1: - return "continue"; - break; - case TC_ACT_OK: - return "pass"; - break; - case TC_ACT_SHOT: - return "drop"; - break; - case TC_ACT_RECLASSIFY: - return "reclassify"; - case TC_ACT_PIPE: - return "pipe"; - case TC_ACT_STOLEN: - return "stolen"; - default: - snprintf(buf, len, "%d", action); - return buf; - } -} - -int action_a2n(char *arg, int *result) -{ - int res; - - if (matches(arg, "continue") == 0) - res = -1; - else if (matches(arg, "drop") == 0) - res = TC_ACT_SHOT; - else if (matches(arg, "shot") == 0) - res = TC_ACT_SHOT; - else if (matches(arg, "pass") == 0) - res = TC_ACT_OK; - else if (strcmp(arg, "ok") == 0) - res = TC_ACT_OK; - else if (matches(arg, "reclassify") == 0) - res = TC_ACT_RECLASSIFY; - else { - char dummy; - if (sscanf(arg, "%d%c", &res, &dummy) != 1) - return -1; - } - *result = res; - return 0; -} - -void print_tm(FILE * f, const struct tcf_t *tm) -{ - int hz = get_user_hz(); - if (tm->install != 0) - fprintf(f, " installed %u sec", (unsigned)(tm->install/hz)); - if (tm->lastuse != 0) - fprintf(f, " used %u sec", (unsigned)(tm->lastuse/hz)); - if (tm->expires != 0) - fprintf(f, " expires %u sec", (unsigned)(tm->expires/hz)); -} - -void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtattr **xstats) -{ - SPRINT_BUF(b1); - struct rtattr *tbs[TCA_STATS_MAX + 1]; - - parse_rtattr_nested(tbs, TCA_STATS_MAX, rta); - - if (tbs[TCA_STATS_BASIC]) { - struct gnet_stats_basic bs = {0}; - memcpy(&bs, RTA_DATA(tbs[TCA_STATS_BASIC]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_BASIC]), sizeof(bs))); - fprintf(fp, "%sSent %llu bytes %u pkt", - prefix, (unsigned long long) bs.bytes, bs.packets); - } - - if (tbs[TCA_STATS_QUEUE]) { - struct gnet_stats_queue q = {0}; - memcpy(&q, RTA_DATA(tbs[TCA_STATS_QUEUE]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_QUEUE]), sizeof(q))); - fprintf(fp, " (dropped %u, overlimits %u requeues %u) ", - q.drops, q.overlimits, q.requeues); - } - - if (tbs[TCA_STATS_RATE_EST]) { - struct gnet_stats_rate_est re = {0}; - memcpy(&re, RTA_DATA(tbs[TCA_STATS_RATE_EST]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_RATE_EST]), sizeof(re))); - fprintf(fp, "\n%srate %s %upps ", - prefix, sprint_rate(re.bps, b1), re.pps); - } - - if (tbs[TCA_STATS_QUEUE]) { - struct gnet_stats_queue q = {0}; - memcpy(&q, RTA_DATA(tbs[TCA_STATS_QUEUE]), MIN(RTA_PAYLOAD(tbs[TCA_STATS_QUEUE]), sizeof(q))); - if (!tbs[TCA_STATS_RATE_EST]) - fprintf(fp, "\n%s", prefix); - fprintf(fp, "backlog %s %up requeues %u ", - sprint_size(q.backlog, b1), q.qlen, q.requeues); - } - - if (xstats) - *xstats = tbs[TCA_STATS_APP] ? : NULL; -} - -void print_tcstats_attr(FILE *fp, struct rtattr *tb[], char *prefix, struct rtattr **xstats) -{ - SPRINT_BUF(b1); - - if (tb[TCA_STATS2]) { - print_tcstats2_attr(fp, tb[TCA_STATS2], prefix, xstats); - if (xstats && NULL == *xstats) - goto compat_xstats; - return; - } - /* backward compatibility */ - if (tb[TCA_STATS]) { - struct tc_stats st; - - /* handle case where kernel returns more/less than we know about */ - memset(&st, 0, sizeof(st)); - memcpy(&st, RTA_DATA(tb[TCA_STATS]), MIN(RTA_PAYLOAD(tb[TCA_STATS]), sizeof(st))); - - fprintf(fp, "%sSent %llu bytes %u pkts (dropped %u, overlimits %u) ", - prefix, (unsigned long long)st.bytes, st.packets, st.drops, - st.overlimits); - - if (st.bps || st.pps || st.qlen || st.backlog) { - fprintf(fp, "\n%s", prefix); - if (st.bps || st.pps) { - fprintf(fp, "rate "); - if (st.bps) - fprintf(fp, "%s ", sprint_rate(st.bps, b1)); - if (st.pps) - fprintf(fp, "%upps ", st.pps); - } - if (st.qlen || st.backlog) { - fprintf(fp, "backlog "); - if (st.backlog) - fprintf(fp, "%s ", sprint_size(st.backlog, b1)); - if (st.qlen) - fprintf(fp, "%up ", st.qlen); - } - } - } - -compat_xstats: - if (tb[TCA_XSTATS] && xstats) - *xstats = tb[TCA_XSTATS]; -} - diff --git a/tc/tc_util.h b/tc/tc_util.h deleted file mode 100644 index 1aa1bda..0000000 --- a/tc/tc_util.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _TC_UTIL_H_ -#define _TC_UTIL_H_ 1 - -#define MAX_MSG 16384 -#include <linux/pkt_sched.h> -#include <linux/pkt_cls.h> -#include <linux/gen_stats.h> -#include "tc_core.h" - -struct qdisc_util -{ - struct qdisc_util *next; - const char *id; - int (*parse_qopt)(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n); - int (*print_qopt)(struct qdisc_util *qu, FILE *f, struct rtattr *opt); - int (*print_xstats)(struct qdisc_util *qu, FILE *f, struct rtattr *xstats); - - int (*parse_copt)(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n); - int (*print_copt)(struct qdisc_util *qu, FILE *f, struct rtattr *opt); -}; - -struct filter_util -{ - struct filter_util *next; - char id[16]; - int (*parse_fopt)(struct filter_util *qu, char *fhandle, int argc, - char **argv, struct nlmsghdr *n); - int (*print_fopt)(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 fhandle); -}; - -struct action_util -{ - struct action_util *next; - char id[16]; - int (*parse_aopt)(struct action_util *a, int *argc, char ***argv, - int code, struct nlmsghdr *n); - int (*print_aopt)(struct action_util *au, FILE *f, struct rtattr *opt); - int (*print_xstats)(struct action_util *au, FILE *f, struct rtattr *xstats); -}; - -extern struct qdisc_util *get_qdisc_kind(const char *str); -extern struct filter_util *get_filter_kind(const char *str); - -extern int get_qdisc_handle(__u32 *h, const char *str); -extern int get_rate(unsigned *rate, const char *str); -extern int get_percent(unsigned *percent, const char *str); -extern int get_size(unsigned *size, const char *str); -extern int get_size_and_cell(unsigned *size, int *cell_log, char *str); -extern int get_usecs(unsigned *usecs, const char *str); -extern void print_rate(char *buf, int len, __u32 rate); -extern void print_size(char *buf, int len, __u32 size); -extern void print_percent(char *buf, int len, __u32 percent); -extern void print_qdisc_handle(char *buf, int len, __u32 h); -extern void print_usecs(char *buf, int len, __u32 usecs); -extern char * sprint_rate(__u32 rate, char *buf); -extern char * sprint_size(__u32 size, char *buf); -extern char * sprint_qdisc_handle(__u32 h, char *buf); -extern char * sprint_tc_classid(__u32 h, char *buf); -extern char * sprint_usecs(__u32 usecs, char *buf); -extern char * sprint_percent(__u32 percent, char *buf); - -extern void print_tcstats_attr(FILE *fp, struct rtattr *tb[], char *prefix, struct rtattr **xstats); -extern void print_tcstats2_attr(FILE *fp, struct rtattr *rta, char *prefix, struct rtattr **xstats); - -extern int get_tc_classid(__u32 *h, const char *str); -extern int print_tc_classid(char *buf, int len, __u32 h); -extern char * sprint_tc_classid(__u32 h, char *buf); - -extern int tc_print_police(FILE *f, struct rtattr *tb); -extern int parse_police(int *, char ***, int, struct nlmsghdr *); - -extern char *action_n2a(int action, char *buf, int len); -extern int action_a2n(char *arg, int *result); -extern int act_parse_police(struct action_util *a,int *, char ***, int, struct nlmsghdr *); -extern int print_police(struct action_util *a, FILE *f, - struct rtattr *tb); -extern int police_print_xstats(struct action_util *a,FILE *f, - struct rtattr *tb); -extern int tc_print_action(FILE *f, const struct rtattr *tb); -extern int tc_print_ipt(FILE *f, const struct rtattr *tb); -extern int parse_action(int *, char ***, int, struct nlmsghdr *); -extern void print_tm(FILE *f, const struct tcf_t *tm); - -#endif diff --git a/testsuite/Makefile b/testsuite/Makefile deleted file mode 100644 index 2a4e0ba..0000000 --- a/testsuite/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -## -- Config -- -DEV := lo -PREFIX := sudo -## -- End Config -- - -TESTS := $(patsubst tests/%,%,$(wildcard tests/*.t)) -IPVERS := $(filter-out iproute2/Makefile,$(wildcard iproute2/*)) -KENV := $(shell cat /proc/config.gz | gunzip | grep ^CONFIG) - -.PHONY: compile listtests alltests configure $(TESTS) - -configure: - echo "Entering iproute2" && cd iproute2 && $(MAKE) configure && cd ..; - -compile: configure - echo "Entering iproute2" && cd iproute2 && $(MAKE) && cd ..; - -listtests: - @for t in $(TESTS); do \ - echo "$$t"; \ - done - -alltests: $(TESTS) - -clean: - @rm -rf results/* - -distclean: clean - echo "Entering iproute2" && cd iproute2 && $(MAKE) distclean && cd ..; - -$(TESTS): - @for i in $(IPVERS); do \ - o=`echo $$i | sed -e 's/iproute2\///'`; \ - echo -n "Running $@ [$$o/`uname -r`]: "; \ - TC="$$i/tc/tc" IP="$$i/ip/ip" DEV="$(DEV)" IPVER="$@" SNAME="$$i" \ - ERRF="results/$@.$$o.err" $(KENV) $(PREFIX) tests/$@ > results/$@.$$o.out; \ - if [ "$$?" = "127" ]; then \ - echo "SKIPPED"; \ - elif [ -e "results/$@.$$o.err" ]; then \ - echo "FAILED"; \ - else \ - echo "PASS"; \ - fi; \ - dmesg > results/$@.$$o.dmesg; \ - done diff --git a/testsuite/configs/all-2.4 b/testsuite/configs/all-2.4 deleted file mode 100644 index cc4131c..0000000 --- a/testsuite/configs/all-2.4 +++ /dev/null @@ -1,848 +0,0 @@ -# -# Automatically generated by make menuconfig: don't edit -# -CONFIG_X86=y -# CONFIG_SBUS is not set -CONFIG_UID16=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# -# Processor type and features -# -# CONFIG_M386 is not set -# CONFIG_M486 is not set -# CONFIG_M586 is not set -# CONFIG_M586TSC is not set -# CONFIG_M586MMX is not set -# CONFIG_M686 is not set -# CONFIG_MPENTIUMIII is not set -CONFIG_MPENTIUM4=y -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MK8 is not set -# CONFIG_MELAN is not set -# CONFIG_MCRUSOE is not set -# CONFIG_MWINCHIPC6 is not set -# CONFIG_MWINCHIP2 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MCYRIXIII is not set -# CONFIG_MVIAC3_2 is not set -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INVLPG=y -CONFIG_X86_CMPXCHG=y -CONFIG_X86_XADD=y -CONFIG_X86_BSWAP=y -CONFIG_X86_POPAD_OK=y -# CONFIG_RWSEM_GENERIC_SPINLOCK is not set -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_X86_L1_CACHE_SHIFT=7 -CONFIG_X86_HAS_TSC=y -CONFIG_X86_GOOD_APIC=y -CONFIG_X86_PGE=y -CONFIG_X86_USE_PPRO_CHECKSUM=y -CONFIG_X86_F00F_WORKS_OK=y -CONFIG_X86_MCE=y -# CONFIG_TOSHIBA is not set -# CONFIG_I8K is not set -# CONFIG_MICROCODE is not set -# CONFIG_X86_MSR is not set -# CONFIG_X86_CPUID is not set -# CONFIG_EDD is not set -CONFIG_NOHIGHMEM=y -# CONFIG_HIGHMEM4G is not set -# CONFIG_HIGHMEM64G is not set -# CONFIG_HIGHMEM is not set -# CONFIG_MATH_EMULATION is not set -# CONFIG_MTRR is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=32 -# CONFIG_X86_NUMA is not set -# CONFIG_X86_TSC_DISABLE is not set -CONFIG_X86_TSC=y -CONFIG_HAVE_DEC_LOCK=y - -# -# General setup -# -CONFIG_NET=y -CONFIG_X86_IO_APIC=y -CONFIG_X86_LOCAL_APIC=y -CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GODIRECT is not set -CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_ISA=y -CONFIG_PCI_NAMES=y -# CONFIG_EISA is not set -# CONFIG_MCA is not set -CONFIG_HOTPLUG=y - -# -# PCMCIA/CardBus support -# -CONFIG_PCMCIA=y -CONFIG_CARDBUS=y -# CONFIG_TCIC is not set -# CONFIG_I82092 is not set -# CONFIG_I82365 is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HOTPLUG_PCI_COMPAQ is not set -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -# CONFIG_HOTPLUG_PCI_IBM is not set -# CONFIG_HOTPLUG_PCI_SHPC is not set -# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set -# CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY is not set -# CONFIG_HOTPLUG_PCI_PCIE is not set -# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=y -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -# CONFIG_OOM_KILLER is not set -CONFIG_PM=y -# CONFIG_APM is not set - -# -# ACPI Support -# -# CONFIG_ACPI is not set -CONFIG_ACPI_BOOT=y - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play configuration -# -CONFIG_PNP=y -CONFIG_ISAPNP=y - -# -# Block devices -# -CONFIG_BLK_DEV_FD=y -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_CISS_SCSI_TAPE is not set -# CONFIG_CISS_MONITOR_THREAD is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_BLK_STATS is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -# CONFIG_IP_ROUTE_VERBOSE is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -CONFIG_ATM=y -CONFIG_ATM_CLIP=y -# CONFIG_ATM_CLIP_NO_ICMP is not set -# CONFIG_ATM_LANE is not set -# CONFIG_ATM_BR2684 is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CBQ=y -CONFIG_NET_SCH_HTB=y -CONFIG_NET_SCH_CSZ=y -CONFIG_NET_SCH_HFSC=y -CONFIG_NET_SCH_ATM=y -CONFIG_NET_SCH_PRIO=y -CONFIG_NET_SCH_RED=y -CONFIG_NET_SCH_SFQ=y -CONFIG_NET_SCH_TEQL=y -CONFIG_NET_SCH_TBF=y -CONFIG_NET_SCH_GRED=y -CONFIG_NET_SCH_NETEM=y -CONFIG_NET_SCH_DSMARK=y -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_CLS=y -CONFIG_NET_CLS_TCINDEX=y -CONFIG_NET_CLS_ROUTE4=y -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=y -CONFIG_NET_CLS_U32=y -CONFIG_NET_CLS_RSVP=y -CONFIG_NET_CLS_RSVP6=y -CONFIG_NET_CLS_POLICE=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set -# CONFIG_BLK_DEV_IDECS is not set -# CONFIG_BLK_DEV_DELKIN is not set -CONFIG_BLK_DEV_IDECD=y -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set -CONFIG_BLK_DEV_CMD640=y -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_ISAPNP is not set -CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_BLK_DEV_GENERIC is not set -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_BLK_DEV_ADMA100 is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_WDC_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_AMD74XX_OVERRIDE is not set -# CONFIG_BLK_DEV_ATIIXP is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_HPT34X_AUTODMA is not set -# CONFIG_BLK_DEV_HPT366 is not set -CONFIG_BLK_DEV_PIIX=y -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_PDC202XX_BURST is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -CONFIG_BLK_DEV_RZ1000=y -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SIS5513 is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_IDE_CHIPSETS is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_ATARAID is not set -# CONFIG_BLK_DEV_ATARAID_PDC is not set -# CONFIG_BLK_DEV_ATARAID_HPT is not set -# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set -# CONFIG_BLK_DEV_ATARAID_SII is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_BOOT is not set -# CONFIG_FUSION_ISENSE is not set -# CONFIG_FUSION_CTL is not set -# CONFIG_FUSION_LAN is not set - -# -# IEEE 1394 (FireWire) support (EXPERIMENTAL) -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -CONFIG_DUMMY=m -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set -# CONFIG_NET_SB1000 is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_B44 is not set -# CONFIG_CS89x0 is not set -# CONFIG_TULIP is not set -# CONFIG_DE4X5 is not set -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -# CONFIG_EEPRO100 is not set -# CONFIG_EEPRO100_PIO is not set -# CONFIG_E100 is not set -# CONFIG_LNE390 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_FORCEDETH is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_8139CP is not set -CONFIG_8139TOO=y -CONFIG_8139TOO_PIO=y -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_SUNDANCE_MMIO is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_RHINE_MMIO is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# PCMCIA network device support -# -# CONFIG_NET_PCMCIA is not set - -# -# ATM drivers -# -# CONFIG_ATM_TCP is not set -# CONFIG_ATM_LANAI is not set -# CONFIG_ATM_ENI is not set -# CONFIG_ATM_FIRESTREAM is not set -# CONFIG_ATM_ZATM is not set -# CONFIG_ATM_NICSTAR is not set -# CONFIG_ATM_IDT77252 is not set -# CONFIG_ATM_AMBASSADOR is not set -# CONFIG_ATM_HORIZON is not set -# CONFIG_ATM_IA is not set -# CONFIG_ATM_FORE200E_MAYBE is not set -# CONFIG_ATM_HE is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_UINPUT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -# CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set -# CONFIG_MK712_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set -# CONFIG_QIC02_TAPE is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_IPMI_PANIC_EVENT is not set -# CONFIG_IPMI_DEVICE_INTERFACE is not set -# CONFIG_IPMI_KCS is not set -# CONFIG_IPMI_WATCHDOG is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_SCx200 is not set -# CONFIG_SCx200_GPIO is not set -# CONFIG_AMD_RNG is not set -# CONFIG_INTEL_RNG is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_AMD_PM768 is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set - -# -# Direct Rendering Manager (XFree86 DRI support) -# -# CONFIG_DRM is not set - -# -# PCMCIA character devices -# -# CONFIG_PCMCIA_SERIAL_CS is not set -# CONFIG_SYNCLINK_CS is not set -# CONFIG_MWAVE is not set -# CONFIG_OBMOUSE is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_QFMT_V2 is not set -# CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=y -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -CONFIG_TMPFS=y -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_XFS_FS is not set -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_RT is not set -# CONFIG_XFS_TRACE is not set -# CONFIG_XFS_DEBUG is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_ROOT_NFS is not set -CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set -CONFIG_NFSD_TCP=y -CONFIG_SUNRPC=y -CONFIG_LOCKD=y -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# Console drivers -# -CONFIG_VGA_CONSOLE=y -# CONFIG_VIDEO_SELECT is not set -# CONFIG_MDA_CONSOLE is not set - -# -# Frame-buffer support -# -# CONFIG_FB is not set - -# -# Sound -# -CONFIG_SOUND=y -# CONFIG_SOUND_ALI5455 is not set -# CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_CMPCI is not set -CONFIG_SOUND_EMU10K1=y -CONFIG_MIDI_EMU10K1=y -# CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_CS4281 is not set -# CONFIG_SOUND_ES1370 is not set -# CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_MAESTRO3 is not set -# CONFIG_SOUND_FORTE is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_RME96XX is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -# CONFIG_MIDI_VIA82CXXX is not set -# CONFIG_SOUND_OSS is not set -# CONFIG_SOUND_TVMIXER is not set -# CONFIG_SOUND_AD1980 is not set -# CONFIG_SOUND_WM97XX is not set - -# -# USB support -# -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -# CONFIG_USB_DEVICEFS is not set -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_EHCI_HCD is not set -CONFIG_USB_UHCI_ALT=y -# CONFIG_USB_OHCI is not set -# CONFIG_USB_SL811HS_ALT is not set -# CONFIG_USB_SL811HS is not set -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_MIDI is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_HID is not set -# CONFIG_USB_HIDINPUT is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_TIGL is not set -# CONFIG_USB_BRLVGER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_SPEEDTOUCH is not set - -# -# Support for USB gadgets -# -# CONFIG_USB_GADGET is not set - -# -# Bluetooth support -# -# CONFIG_BLUEZ is not set - -# -# Kernel hacking -# -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_STACKOVERFLOW=y -CONFIG_DEBUG_HIGHMEM=y -CONFIG_DEBUG_SLAB=y -CONFIG_DEBUG_IOVIRT=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_FRAME_POINTER=y -CONFIG_LOG_BUF_SHIFT=0 - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_CRC32=y -# CONFIG_ZLIB_INFLATE is not set -# CONFIG_ZLIB_DEFLATE is not set -# CONFIG_FW_LOADER is not set diff --git a/testsuite/configs/all-no-act b/testsuite/configs/all-no-act deleted file mode 100644 index baeed43..0000000 --- a/testsuite/configs/all-no-act +++ /dev/null @@ -1,1499 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-rc2-bk13 -# Wed Dec 8 14:43:07 2004 -# -CONFIG_X86=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_LOCK_KERNEL=y - -# -# General setup -# -CONFIG_LOCALVERSION="no-act" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -CONFIG_AUDIT=y -CONFIG_AUDITSYSCALL=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_FUTEX=y -CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y -CONFIG_STOP_MACHINE=y - -# -# Processor type and features -# -CONFIG_X86_PC=y -# CONFIG_X86_ELAN is not set -# CONFIG_X86_VOYAGER is not set -# CONFIG_X86_NUMAQ is not set -# CONFIG_X86_SUMMIT is not set -# CONFIG_X86_BIGSMP is not set -# CONFIG_X86_VISWS is not set -# CONFIG_X86_GENERICARCH is not set -# CONFIG_X86_ES7000 is not set -# CONFIG_M386 is not set -# CONFIG_M486 is not set -# CONFIG_M586 is not set -# CONFIG_M586TSC is not set -# CONFIG_M586MMX is not set -# CONFIG_M686 is not set -# CONFIG_MPENTIUMII is not set -# CONFIG_MPENTIUMIII is not set -# CONFIG_MPENTIUMM is not set -CONFIG_MPENTIUM4=y -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MK8 is not set -# CONFIG_MCRUSOE is not set -# CONFIG_MEFFICEON is not set -# CONFIG_MWINCHIPC6 is not set -# CONFIG_MWINCHIP2 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MCYRIXIII is not set -# CONFIG_MVIAC3_2 is not set -# CONFIG_X86_GENERIC is not set -CONFIG_X86_CMPXCHG=y -CONFIG_X86_XADD=y -CONFIG_X86_L1_CACHE_SHIFT=7 -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INVLPG=y -CONFIG_X86_BSWAP=y -CONFIG_X86_POPAD_OK=y -CONFIG_X86_GOOD_APIC=y -CONFIG_X86_INTEL_USERCOPY=y -CONFIG_X86_USE_PPRO_CHECKSUM=y -# CONFIG_HPET_TIMER is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=8 -# CONFIG_SCHED_SMT is not set -CONFIG_PREEMPT=y -CONFIG_X86_LOCAL_APIC=y -CONFIG_X86_IO_APIC=y -CONFIG_X86_TSC=y -CONFIG_X86_MCE=y -CONFIG_X86_MCE_NONFATAL=y -# CONFIG_X86_MCE_P4THERMAL is not set -# CONFIG_TOSHIBA is not set -# CONFIG_I8K is not set -# CONFIG_MICROCODE is not set -# CONFIG_X86_MSR is not set -# CONFIG_X86_CPUID is not set - -# -# Firmware Drivers -# -# CONFIG_EDD is not set -CONFIG_NOHIGHMEM=y -# CONFIG_HIGHMEM4G is not set -# CONFIG_HIGHMEM64G is not set -# CONFIG_MATH_EMULATION is not set -CONFIG_MTRR=y -# CONFIG_EFI is not set -CONFIG_IRQBALANCE=y -CONFIG_HAVE_DEC_LOCK=y -# CONFIG_REGPARM is not set - -# -# Power management options (ACPI, APM) -# -CONFIG_PM=y -# CONFIG_PM_DEBUG is not set -CONFIG_SOFTWARE_SUSPEND=y -CONFIG_PM_STD_PARTITION="" - -# -# ACPI (Advanced Configuration and Power Interface) Support -# -CONFIG_ACPI=y -CONFIG_ACPI_BOOT=y -CONFIG_ACPI_INTERPRETER=y -CONFIG_ACPI_SLEEP=y -CONFIG_ACPI_SLEEP_PROC_FS=y -CONFIG_ACPI_AC=y -CONFIG_ACPI_BATTERY=y -CONFIG_ACPI_BUTTON=y -CONFIG_ACPI_VIDEO=y -CONFIG_ACPI_FAN=y -CONFIG_ACPI_PROCESSOR=y -CONFIG_ACPI_THERMAL=y -# CONFIG_ACPI_ASUS is not set -# CONFIG_ACPI_IBM is not set -# CONFIG_ACPI_TOSHIBA is not set -# CONFIG_ACPI_CUSTOM_DSDT is not set -CONFIG_ACPI_BLACKLIST_YEAR=0 -# CONFIG_ACPI_DEBUG is not set -CONFIG_ACPI_BUS=y -CONFIG_ACPI_EC=y -CONFIG_ACPI_POWER=y -CONFIG_ACPI_PCI=y -CONFIG_ACPI_SYSTEM=y -# CONFIG_X86_PM_TIMER is not set - -# -# APM (Advanced Power Management) BIOS Support -# -# CONFIG_APM is not set - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# Bus options (PCI, PCMCIA, EISA, MCA, ISA) -# -CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GOMMCONFIG is not set -# CONFIG_PCI_GODIRECT is not set -CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_PCI_MMCONFIG=y -# CONFIG_PCI_MSI is not set -CONFIG_PCI_LEGACY_PROC=y -CONFIG_PCI_NAMES=y -CONFIG_ISA=y -# CONFIG_EISA is not set -# CONFIG_MCA is not set -# CONFIG_SCx200 is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PC-card bridges -# -CONFIG_PCMCIA_PROBE=y - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=y -CONFIG_BINFMT_MISC=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -# CONFIG_STANDALONE is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_DEBUG_DRIVER is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -CONFIG_PNP=y -# CONFIG_PNP_DEBUG is not set - -# -# Protocols -# -# CONFIG_ISAPNP is not set -# CONFIG_PNPBIOS is not set -CONFIG_PNPACPI=y - -# -# Block devices -# -CONFIG_BLK_DEV_FD=y -# CONFIG_BLK_DEV_XD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_CRYPTOLOOP=y -CONFIG_BLK_DEV_NBD=y -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_LBD=y -CONFIG_CDROM_PKTCDVD=y -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -# CONFIG_BLK_DEV_HD_IDE is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -CONFIG_BLK_DEV_IDECD=y -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_CMD640=y -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_IDEPNP is not set -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_RZ1000 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_ATIIXP is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -CONFIG_BLK_DEV_SIS5513=y -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_IDE_ARM is not set -# CONFIG_IDE_CHIPSETS is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -CONFIG_SCSI=y -# CONFIG_SCSI_PROC_FS is not set - -# -# SCSI support type (disk, tape, CD-ROM) -# -# CONFIG_BLK_DEV_SD is not set -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA2XXX=y -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_ULTRASTOR is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -CONFIG_I2O=y -CONFIG_I2O_CONFIG=y -CONFIG_I2O_BLOCK=y -# CONFIG_I2O_SCSI is not set -CONFIG_I2O_PROC=y - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE=y -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_ARPD=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -CONFIG_INET_TUNNEL=y -CONFIG_IP_TCPDIAG=y -CONFIG_IP_TCPDIAG_IPV6=y - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_INET6_TUNNEL=y -CONFIG_IPV6_TUNNEL=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_BRIDGE_NETFILTER=y - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=y -CONFIG_IP_NF_CT_ACCT=y -CONFIG_IP_NF_CONNTRACK_MARK=y -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -CONFIG_IP_NF_FTP=y -CONFIG_IP_NF_IRC=y -CONFIG_IP_NF_TFTP=y -# CONFIG_IP_NF_AMANDA is not set -CONFIG_IP_NF_QUEUE=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_LIMIT=y -CONFIG_IP_NF_MATCH_IPRANGE=y -CONFIG_IP_NF_MATCH_MAC=y -CONFIG_IP_NF_MATCH_PKTTYPE=y -CONFIG_IP_NF_MATCH_MARK=y -CONFIG_IP_NF_MATCH_MULTIPORT=y -CONFIG_IP_NF_MATCH_TOS=y -CONFIG_IP_NF_MATCH_RECENT=y -CONFIG_IP_NF_MATCH_ECN=y -CONFIG_IP_NF_MATCH_DSCP=y -CONFIG_IP_NF_MATCH_AH_ESP=y -CONFIG_IP_NF_MATCH_LENGTH=y -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_MATCH_TCPMSS=y -CONFIG_IP_NF_MATCH_HELPER=y -CONFIG_IP_NF_MATCH_STATE=y -CONFIG_IP_NF_MATCH_CONNTRACK=y -CONFIG_IP_NF_MATCH_OWNER=y -CONFIG_IP_NF_MATCH_PHYSDEV=y -CONFIG_IP_NF_MATCH_ADDRTYPE=y -CONFIG_IP_NF_MATCH_REALM=y -# CONFIG_IP_NF_MATCH_SCTP is not set -CONFIG_IP_NF_MATCH_COMMENT=y -CONFIG_IP_NF_MATCH_CONNMARK=y -CONFIG_IP_NF_MATCH_HASHLIMIT=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_TARGET_LOG=y -CONFIG_IP_NF_TARGET_ULOG=y -CONFIG_IP_NF_TARGET_TCPMSS=y -CONFIG_IP_NF_NAT=y -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_IP_NF_TARGET_NETMAP=y -CONFIG_IP_NF_TARGET_SAME=y -# CONFIG_IP_NF_NAT_LOCAL is not set -# CONFIG_IP_NF_NAT_SNMP_BASIC is not set -CONFIG_IP_NF_NAT_IRC=y -CONFIG_IP_NF_NAT_FTP=y -CONFIG_IP_NF_NAT_TFTP=y -CONFIG_IP_NF_MANGLE=y -CONFIG_IP_NF_TARGET_TOS=y -CONFIG_IP_NF_TARGET_ECN=y -CONFIG_IP_NF_TARGET_DSCP=y -CONFIG_IP_NF_TARGET_MARK=y -CONFIG_IP_NF_TARGET_CLASSIFY=y -CONFIG_IP_NF_TARGET_CONNMARK=y -CONFIG_IP_NF_TARGET_CLUSTERIP=y -CONFIG_IP_NF_RAW=y -CONFIG_IP_NF_TARGET_NOTRACK=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y - -# -# IPv6: Netfilter Configuration -# -CONFIG_IP6_NF_QUEUE=y -CONFIG_IP6_NF_IPTABLES=y -CONFIG_IP6_NF_MATCH_LIMIT=y -CONFIG_IP6_NF_MATCH_MAC=y -CONFIG_IP6_NF_MATCH_RT=y -CONFIG_IP6_NF_MATCH_OPTS=y -CONFIG_IP6_NF_MATCH_FRAG=y -CONFIG_IP6_NF_MATCH_HL=y -CONFIG_IP6_NF_MATCH_MULTIPORT=y -CONFIG_IP6_NF_MATCH_OWNER=y -CONFIG_IP6_NF_MATCH_MARK=y -CONFIG_IP6_NF_MATCH_IPV6HEADER=y -CONFIG_IP6_NF_MATCH_AHESP=y -CONFIG_IP6_NF_MATCH_LENGTH=y -CONFIG_IP6_NF_MATCH_EUI64=y -CONFIG_IP6_NF_MATCH_PHYSDEV=y -CONFIG_IP6_NF_FILTER=y -CONFIG_IP6_NF_TARGET_LOG=y -CONFIG_IP6_NF_MANGLE=y -CONFIG_IP6_NF_TARGET_MARK=y -CONFIG_IP6_NF_RAW=y - -# -# Bridge: Netfilter Configuration -# -# CONFIG_BRIDGE_NF_EBTABLES is not set -CONFIG_XFRM=y -CONFIG_XFRM_USER=y - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -CONFIG_ATM=y -# CONFIG_ATM_CLIP is not set -# CONFIG_ATM_LANE is not set -# CONFIG_ATM_BR2684 is not set -CONFIG_BRIDGE=y -CONFIG_VLAN_8021Q=y -# CONFIG_DECNET is not set -CONFIG_LLC=y -CONFIG_LLC2=y -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CLK_JIFFIES=y -# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set -# CONFIG_NET_SCH_CLK_CPU is not set -CONFIG_NET_SCH_CBQ=y -CONFIG_NET_SCH_HTB=y -CONFIG_NET_SCH_HFSC=y -CONFIG_NET_SCH_ATM=y -CONFIG_NET_SCH_PRIO=y -CONFIG_NET_SCH_RED=y -CONFIG_NET_SCH_SFQ=y -CONFIG_NET_SCH_TEQL=y -CONFIG_NET_SCH_TBF=y -CONFIG_NET_SCH_GRED=y -CONFIG_NET_SCH_DSMARK=y -CONFIG_NET_SCH_NETEM=y -CONFIG_NET_SCH_INGRESS=y -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_CLS=y -CONFIG_NET_CLS_TCINDEX=y -CONFIG_NET_CLS_ROUTE4=y -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=y -CONFIG_NET_CLS_U32=y -CONFIG_NET_CLS_EGP=y -CONFIG_EGP_DEBUG=y -CONFIG_NET_CLS_EGP_SIMPLE_CMP=y -CONFIG_NET_CLS_EGP_NBYTE=y -CONFIG_NET_CLS_EGP_KMP=y -CONFIG_NET_CLS_EGP_REGEXP=y -CONFIG_NET_CLS_EGP_CMD=y -CONFIG_EGP_CMD_BACK_TTL=4096 -CONFIG_CLS_U32_PERF=y -CONFIG_NET_CLS_IND=y -CONFIG_NET_CLS_RSVP=y -CONFIG_NET_CLS_RSVP6=y -# CONFIG_NET_CLS_ACT is not set -CONFIG_NET_CLS_POLICE=y - -# -# Network testing -# -CONFIG_NET_PKTGEN=y -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=y -# CONFIG_NET_SB1000 is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_CS89x0 is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -CONFIG_8139TOO=y -CONFIG_8139TOO_PIO=y -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# ATM drivers -# -# CONFIG_ATM_TCP is not set -# CONFIG_ATM_LANAI is not set -# CONFIG_ATM_ENI is not set -# CONFIG_ATM_FIRESTREAM is not set -# CONFIG_ATM_ZATM is not set -# CONFIG_ATM_NICSTAR is not set -# CONFIG_ATM_IDT77252 is not set -# CONFIG_ATM_AMBASSADOR is not set -# CONFIG_ATM_HORIZON is not set -# CONFIG_ATM_IA is not set -# CONFIG_ATM_FORE200E_MAYBE is not set -# CONFIG_ATM_HE is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PPP=y -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -CONFIG_PPP_BSDCOMP=y -# CONFIG_PPPOE is not set -# CONFIG_PPPOATM is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -CONFIG_SHAPER=y -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_INPORT is not set -# CONFIG_MOUSE_LOGIBM is not set -# CONFIG_MOUSE_PC110PAD is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_CONSOLE is not set -# CONFIG_SERIAL_8250_ACPI is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_MWAVE is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_HPET is not set -# CONFIG_HANGCHECK_TIMER is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -CONFIG_I2C_ALGOBIT=y -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_ISA is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -CONFIG_I2C_SIS96X=y -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Hardware Sensors Chip support -# -CONFIG_I2C_SENSOR=y -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set - -# -# Other I2C Chip support -# -CONFIG_SENSORS_EEPROM=y -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Misc devices -# -# CONFIG_IBM_ASM is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set -# CONFIG_VIDEO_SELECT is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -CONFIG_SND_HWDEP=y -CONFIG_SND_RAWMIDI=y -CONFIG_SND_SEQUENCER=y -# CONFIG_SND_SEQ_DUMMY is not set -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set - -# -# Generic devices -# -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_VIRMIDI is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# ISA devices -# -# CONFIG_SND_AD1848 is not set -# CONFIG_SND_CS4231 is not set -# CONFIG_SND_CS4232 is not set -# CONFIG_SND_CS4236 is not set -# CONFIG_SND_ES1688 is not set -# CONFIG_SND_ES18XX is not set -# CONFIG_SND_GUSCLASSIC is not set -# CONFIG_SND_GUSEXTREME is not set -# CONFIG_SND_GUSMAX is not set -# CONFIG_SND_INTERWAVE is not set -# CONFIG_SND_INTERWAVE_STB is not set -# CONFIG_SND_OPTI92X_AD1848 is not set -# CONFIG_SND_OPTI92X_CS4231 is not set -# CONFIG_SND_OPTI93X is not set -# CONFIG_SND_SB8 is not set -# CONFIG_SND_SB16 is not set -# CONFIG_SND_SBAWE is not set -# CONFIG_SND_WAVEFRONT is not set -# CONFIG_SND_CMI8330 is not set -# CONFIG_SND_OPL3SA2 is not set -# CONFIG_SND_SGALAXY is not set -# CONFIG_SND_SSCAPE is not set - -# -# PCI devices -# -CONFIG_SND_AC97_CODEC=y -# CONFIG_SND_ALI5451 is not set -# CONFIG_SND_ATIIXP is not set -# CONFIG_SND_ATIIXP_MODEM is not set -# CONFIG_SND_AU8810 is not set -# CONFIG_SND_AU8820 is not set -# CONFIG_SND_AU8830 is not set -# CONFIG_SND_AZT3328 is not set -# CONFIG_SND_BT87X is not set -# CONFIG_SND_CS46XX is not set -# CONFIG_SND_CS4281 is not set -CONFIG_SND_EMU10K1=y -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set -# CONFIG_SND_HDSP is not set -# CONFIG_SND_TRIDENT is not set -# CONFIG_SND_YMFPCI is not set -# CONFIG_SND_ALS4000 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_ENS1370 is not set -# CONFIG_SND_ENS1371 is not set -# CONFIG_SND_ES1938 is not set -# CONFIG_SND_ES1968 is not set -# CONFIG_SND_MAESTRO3 is not set -# CONFIG_SND_FM801 is not set -# CONFIG_SND_ICE1712 is not set -# CONFIG_SND_ICE1724 is not set -# CONFIG_SND_INTEL8X0 is not set -# CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_VIA82XX is not set -# CONFIG_SND_VX222 is not set - -# -# USB devices -# -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_USX2Y is not set - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set - -# -# USB support -# -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set -# CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y - -# -# USB Host Controller Drivers -# -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_OHCI_HCD is not set -CONFIG_USB_UHCI_HCD=y - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH_TTY is not set -# CONFIG_USB_MIDI is not set -# CONFIG_USB_ACM is not set -CONFIG_USB_PRINTER=y -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_RW_DETECT is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT=y -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -CONFIG_USB_EGALAX=m -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# -# CONFIG_USB_DABUSB is not set - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_TIGL is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -CONFIG_USB_CYTHERM=m -# CONFIG_USB_PHIDGETKIT is not set -CONFIG_USB_PHIDGETSERVO=m -# CONFIG_USB_TEST is not set - -# -# USB ATM/DSL drivers -# -# CONFIG_USB_ATM is not set -# CONFIG_USB_SPEEDTOUCH is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=y - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -CONFIG_UDF_FS=y -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set -CONFIG_NFSD_TCP=y -CONFIG_LOCKD=y -CONFIG_EXPORTFS=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Profiling support -# -CONFIG_PROFILING=y -CONFIG_OPROFILE=y - -# -# Kernel hacking -# -CONFIG_DEBUG_KERNEL=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_SCHEDSTATS is not set -CONFIG_DEBUG_SLAB=y -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_INFO is not set -CONFIG_FRAME_POINTER=y -CONFIG_EARLY_PRINTK=y -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_KPROBES is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_4KSTACKS is not set -CONFIG_X86_FIND_SMP_CONFIG=y -CONFIG_X86_MPPARSE=y - -# -# Security options -# -# CONFIG_KEYS is not set -CONFIG_SECURITY=y -CONFIG_SECURITY_NETWORK=y -CONFIG_SECURITY_CAPABILITIES=m -CONFIG_SECURITY_ROOTPLUG=m -# CONFIG_SECURITY_SECLVL is not set -CONFIG_SECURITY_SELINUX=y -# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set -CONFIG_SECURITY_SELINUX_DISABLE=y -CONFIG_SECURITY_SELINUX_DEVELOP=y -# CONFIG_SECURITY_SELINUX_MLS is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_WP512=y -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_BLOWFISH=y -CONFIG_CRYPTO_TWOFISH=y -CONFIG_CRYPTO_SERPENT=y -CONFIG_CRYPTO_AES_586=y -CONFIG_CRYPTO_CAST5=y -CONFIG_CRYPTO_CAST6=y -CONFIG_CRYPTO_TEA=y -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_KHAZAD=y -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_MICHAEL_MIC=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_TEST=y - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -CONFIG_CRC32=y -CONFIG_LIBCRC32C=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_X86_SMP=y -CONFIG_X86_HT=y -CONFIG_X86_BIOS_REBOOT=y -CONFIG_X86_TRAMPOLINE=y -CONFIG_PC=y diff --git a/testsuite/configs/all-police-act b/testsuite/configs/all-police-act deleted file mode 100644 index 1c84282..0000000 --- a/testsuite/configs/all-police-act +++ /dev/null @@ -1,1504 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-rc2-bk13 -# Wed Dec 8 14:19:17 2004 -# -CONFIG_X86=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_LOCK_KERNEL=y - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -CONFIG_AUDIT=y -CONFIG_AUDITSYSCALL=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_FUTEX=y -CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y -CONFIG_STOP_MACHINE=y - -# -# Processor type and features -# -CONFIG_X86_PC=y -# CONFIG_X86_ELAN is not set -# CONFIG_X86_VOYAGER is not set -# CONFIG_X86_NUMAQ is not set -# CONFIG_X86_SUMMIT is not set -# CONFIG_X86_BIGSMP is not set -# CONFIG_X86_VISWS is not set -# CONFIG_X86_GENERICARCH is not set -# CONFIG_X86_ES7000 is not set -# CONFIG_M386 is not set -# CONFIG_M486 is not set -# CONFIG_M586 is not set -# CONFIG_M586TSC is not set -# CONFIG_M586MMX is not set -# CONFIG_M686 is not set -# CONFIG_MPENTIUMII is not set -# CONFIG_MPENTIUMIII is not set -# CONFIG_MPENTIUMM is not set -CONFIG_MPENTIUM4=y -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MK8 is not set -# CONFIG_MCRUSOE is not set -# CONFIG_MEFFICEON is not set -# CONFIG_MWINCHIPC6 is not set -# CONFIG_MWINCHIP2 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MCYRIXIII is not set -# CONFIG_MVIAC3_2 is not set -# CONFIG_X86_GENERIC is not set -CONFIG_X86_CMPXCHG=y -CONFIG_X86_XADD=y -CONFIG_X86_L1_CACHE_SHIFT=7 -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INVLPG=y -CONFIG_X86_BSWAP=y -CONFIG_X86_POPAD_OK=y -CONFIG_X86_GOOD_APIC=y -CONFIG_X86_INTEL_USERCOPY=y -CONFIG_X86_USE_PPRO_CHECKSUM=y -# CONFIG_HPET_TIMER is not set -CONFIG_SMP=y -CONFIG_NR_CPUS=8 -# CONFIG_SCHED_SMT is not set -CONFIG_PREEMPT=y -CONFIG_X86_LOCAL_APIC=y -CONFIG_X86_IO_APIC=y -CONFIG_X86_TSC=y -CONFIG_X86_MCE=y -CONFIG_X86_MCE_NONFATAL=y -# CONFIG_X86_MCE_P4THERMAL is not set -# CONFIG_TOSHIBA is not set -# CONFIG_I8K is not set -# CONFIG_MICROCODE is not set -# CONFIG_X86_MSR is not set -# CONFIG_X86_CPUID is not set - -# -# Firmware Drivers -# -# CONFIG_EDD is not set -CONFIG_NOHIGHMEM=y -# CONFIG_HIGHMEM4G is not set -# CONFIG_HIGHMEM64G is not set -# CONFIG_MATH_EMULATION is not set -CONFIG_MTRR=y -# CONFIG_EFI is not set -CONFIG_IRQBALANCE=y -CONFIG_HAVE_DEC_LOCK=y -# CONFIG_REGPARM is not set - -# -# Power management options (ACPI, APM) -# -CONFIG_PM=y -# CONFIG_PM_DEBUG is not set -CONFIG_SOFTWARE_SUSPEND=y -CONFIG_PM_STD_PARTITION="" - -# -# ACPI (Advanced Configuration and Power Interface) Support -# -CONFIG_ACPI=y -CONFIG_ACPI_BOOT=y -CONFIG_ACPI_INTERPRETER=y -CONFIG_ACPI_SLEEP=y -CONFIG_ACPI_SLEEP_PROC_FS=y -CONFIG_ACPI_AC=y -CONFIG_ACPI_BATTERY=y -CONFIG_ACPI_BUTTON=y -CONFIG_ACPI_VIDEO=y -CONFIG_ACPI_FAN=y -CONFIG_ACPI_PROCESSOR=y -CONFIG_ACPI_THERMAL=y -# CONFIG_ACPI_ASUS is not set -# CONFIG_ACPI_IBM is not set -# CONFIG_ACPI_TOSHIBA is not set -# CONFIG_ACPI_CUSTOM_DSDT is not set -CONFIG_ACPI_BLACKLIST_YEAR=0 -# CONFIG_ACPI_DEBUG is not set -CONFIG_ACPI_BUS=y -CONFIG_ACPI_EC=y -CONFIG_ACPI_POWER=y -CONFIG_ACPI_PCI=y -CONFIG_ACPI_SYSTEM=y -# CONFIG_X86_PM_TIMER is not set - -# -# APM (Advanced Power Management) BIOS Support -# -# CONFIG_APM is not set - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# Bus options (PCI, PCMCIA, EISA, MCA, ISA) -# -CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GOMMCONFIG is not set -# CONFIG_PCI_GODIRECT is not set -CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_PCI_MMCONFIG=y -# CONFIG_PCI_MSI is not set -CONFIG_PCI_LEGACY_PROC=y -CONFIG_PCI_NAMES=y -CONFIG_ISA=y -# CONFIG_EISA is not set -# CONFIG_MCA is not set -# CONFIG_SCx200 is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PC-card bridges -# -CONFIG_PCMCIA_PROBE=y - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=y -CONFIG_BINFMT_MISC=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -# CONFIG_STANDALONE is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_DEBUG_DRIVER is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -CONFIG_PNP=y -# CONFIG_PNP_DEBUG is not set - -# -# Protocols -# -# CONFIG_ISAPNP is not set -# CONFIG_PNPBIOS is not set -CONFIG_PNPACPI=y - -# -# Block devices -# -CONFIG_BLK_DEV_FD=y -# CONFIG_BLK_DEV_XD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_CRYPTOLOOP=y -CONFIG_BLK_DEV_NBD=y -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_LBD=y -CONFIG_CDROM_PKTCDVD=y -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -# CONFIG_BLK_DEV_HD_IDE is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -CONFIG_BLK_DEV_IDECD=y -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_CMD640=y -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_IDEPNP is not set -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_RZ1000 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_ATIIXP is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -CONFIG_BLK_DEV_SIS5513=y -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_IDE_ARM is not set -# CONFIG_IDE_CHIPSETS is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -CONFIG_SCSI=y -# CONFIG_SCSI_PROC_FS is not set - -# -# SCSI support type (disk, tape, CD-ROM) -# -# CONFIG_BLK_DEV_SD is not set -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA2XXX=y -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_ULTRASTOR is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -CONFIG_I2O=y -CONFIG_I2O_CONFIG=y -CONFIG_I2O_BLOCK=y -# CONFIG_I2O_SCSI is not set -CONFIG_I2O_PROC=y - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=y -CONFIG_NET_IPGRE=y -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_ARPD=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -CONFIG_INET_TUNNEL=y -CONFIG_IP_TCPDIAG=y -CONFIG_IP_TCPDIAG_IPV6=y - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_INET6_TUNNEL=y -CONFIG_IPV6_TUNNEL=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_BRIDGE_NETFILTER=y - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=y -CONFIG_IP_NF_CT_ACCT=y -CONFIG_IP_NF_CONNTRACK_MARK=y -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -CONFIG_IP_NF_FTP=y -CONFIG_IP_NF_IRC=y -CONFIG_IP_NF_TFTP=y -# CONFIG_IP_NF_AMANDA is not set -CONFIG_IP_NF_QUEUE=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_LIMIT=y -CONFIG_IP_NF_MATCH_IPRANGE=y -CONFIG_IP_NF_MATCH_MAC=y -CONFIG_IP_NF_MATCH_PKTTYPE=y -CONFIG_IP_NF_MATCH_MARK=y -CONFIG_IP_NF_MATCH_MULTIPORT=y -CONFIG_IP_NF_MATCH_TOS=y -CONFIG_IP_NF_MATCH_RECENT=y -CONFIG_IP_NF_MATCH_ECN=y -CONFIG_IP_NF_MATCH_DSCP=y -CONFIG_IP_NF_MATCH_AH_ESP=y -CONFIG_IP_NF_MATCH_LENGTH=y -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_MATCH_TCPMSS=y -CONFIG_IP_NF_MATCH_HELPER=y -CONFIG_IP_NF_MATCH_STATE=y -CONFIG_IP_NF_MATCH_CONNTRACK=y -CONFIG_IP_NF_MATCH_OWNER=y -CONFIG_IP_NF_MATCH_PHYSDEV=y -CONFIG_IP_NF_MATCH_ADDRTYPE=y -CONFIG_IP_NF_MATCH_REALM=y -# CONFIG_IP_NF_MATCH_SCTP is not set -CONFIG_IP_NF_MATCH_COMMENT=y -CONFIG_IP_NF_MATCH_CONNMARK=y -CONFIG_IP_NF_MATCH_HASHLIMIT=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_TARGET_LOG=y -CONFIG_IP_NF_TARGET_ULOG=y -CONFIG_IP_NF_TARGET_TCPMSS=y -CONFIG_IP_NF_NAT=y -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_IP_NF_TARGET_NETMAP=y -CONFIG_IP_NF_TARGET_SAME=y -# CONFIG_IP_NF_NAT_LOCAL is not set -# CONFIG_IP_NF_NAT_SNMP_BASIC is not set -CONFIG_IP_NF_NAT_IRC=y -CONFIG_IP_NF_NAT_FTP=y -CONFIG_IP_NF_NAT_TFTP=y -CONFIG_IP_NF_MANGLE=y -CONFIG_IP_NF_TARGET_TOS=y -CONFIG_IP_NF_TARGET_ECN=y -CONFIG_IP_NF_TARGET_DSCP=y -CONFIG_IP_NF_TARGET_MARK=y -CONFIG_IP_NF_TARGET_CLASSIFY=y -CONFIG_IP_NF_TARGET_CONNMARK=y -CONFIG_IP_NF_TARGET_CLUSTERIP=y -CONFIG_IP_NF_RAW=y -CONFIG_IP_NF_TARGET_NOTRACK=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y - -# -# IPv6: Netfilter Configuration -# -CONFIG_IP6_NF_QUEUE=y -CONFIG_IP6_NF_IPTABLES=y -CONFIG_IP6_NF_MATCH_LIMIT=y -CONFIG_IP6_NF_MATCH_MAC=y -CONFIG_IP6_NF_MATCH_RT=y -CONFIG_IP6_NF_MATCH_OPTS=y -CONFIG_IP6_NF_MATCH_FRAG=y -CONFIG_IP6_NF_MATCH_HL=y -CONFIG_IP6_NF_MATCH_MULTIPORT=y -CONFIG_IP6_NF_MATCH_OWNER=y -CONFIG_IP6_NF_MATCH_MARK=y -CONFIG_IP6_NF_MATCH_IPV6HEADER=y -CONFIG_IP6_NF_MATCH_AHESP=y -CONFIG_IP6_NF_MATCH_LENGTH=y -CONFIG_IP6_NF_MATCH_EUI64=y -CONFIG_IP6_NF_MATCH_PHYSDEV=y -CONFIG_IP6_NF_FILTER=y -CONFIG_IP6_NF_TARGET_LOG=y -CONFIG_IP6_NF_MANGLE=y -CONFIG_IP6_NF_TARGET_MARK=y -CONFIG_IP6_NF_RAW=y - -# -# Bridge: Netfilter Configuration -# -# CONFIG_BRIDGE_NF_EBTABLES is not set -CONFIG_XFRM=y -CONFIG_XFRM_USER=y - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -CONFIG_ATM=y -# CONFIG_ATM_CLIP is not set -# CONFIG_ATM_LANE is not set -# CONFIG_ATM_BR2684 is not set -CONFIG_BRIDGE=y -CONFIG_VLAN_8021Q=y -# CONFIG_DECNET is not set -CONFIG_LLC=y -CONFIG_LLC2=y -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CLK_JIFFIES=y -# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set -# CONFIG_NET_SCH_CLK_CPU is not set -CONFIG_NET_SCH_CBQ=y -CONFIG_NET_SCH_HTB=y -CONFIG_NET_SCH_HFSC=y -CONFIG_NET_SCH_ATM=y -CONFIG_NET_SCH_PRIO=y -CONFIG_NET_SCH_RED=y -CONFIG_NET_SCH_SFQ=y -CONFIG_NET_SCH_TEQL=y -CONFIG_NET_SCH_TBF=y -CONFIG_NET_SCH_GRED=y -CONFIG_NET_SCH_DSMARK=y -CONFIG_NET_SCH_NETEM=y -CONFIG_NET_SCH_INGRESS=y -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_CLS=y -CONFIG_NET_CLS_TCINDEX=y -CONFIG_NET_CLS_ROUTE4=y -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=y -CONFIG_NET_CLS_U32=y -CONFIG_NET_CLS_EGP=y -CONFIG_EGP_DEBUG=y -CONFIG_NET_CLS_EGP_SIMPLE_CMP=y -CONFIG_NET_CLS_EGP_NBYTE=y -CONFIG_NET_CLS_EGP_KMP=y -CONFIG_NET_CLS_EGP_REGEXP=y -CONFIG_NET_CLS_EGP_CMD=y -CONFIG_EGP_CMD_BACK_TTL=4096 -CONFIG_CLS_U32_PERF=y -CONFIG_NET_CLS_IND=y -CONFIG_NET_CLS_RSVP=y -CONFIG_NET_CLS_RSVP6=y -CONFIG_NET_CLS_ACT=y -CONFIG_NET_ACT_POLICE=y -CONFIG_NET_ACT_GACT=y -CONFIG_GACT_PROB=y -CONFIG_NET_ACT_MIRRED=y -CONFIG_NET_ACT_IPT=y -CONFIG_NET_ACT_PEDIT=y - -# -# Network testing -# -CONFIG_NET_PKTGEN=y -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=y -# CONFIG_NET_SB1000 is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_CS89x0 is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -CONFIG_8139TOO=y -CONFIG_8139TOO_PIO=y -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# ATM drivers -# -# CONFIG_ATM_TCP is not set -# CONFIG_ATM_LANAI is not set -# CONFIG_ATM_ENI is not set -# CONFIG_ATM_FIRESTREAM is not set -# CONFIG_ATM_ZATM is not set -# CONFIG_ATM_NICSTAR is not set -# CONFIG_ATM_IDT77252 is not set -# CONFIG_ATM_AMBASSADOR is not set -# CONFIG_ATM_HORIZON is not set -# CONFIG_ATM_IA is not set -# CONFIG_ATM_FORE200E_MAYBE is not set -# CONFIG_ATM_HE is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PPP=y -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -CONFIG_PPP_BSDCOMP=y -# CONFIG_PPPOE is not set -# CONFIG_PPPOATM is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -CONFIG_SHAPER=y -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_INPORT is not set -# CONFIG_MOUSE_LOGIBM is not set -# CONFIG_MOUSE_PC110PAD is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_CONSOLE is not set -# CONFIG_SERIAL_8250_ACPI is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_MWAVE is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_HPET is not set -# CONFIG_HANGCHECK_TIMER is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -CONFIG_I2C_ALGOBIT=y -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_ISA is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -CONFIG_I2C_SIS96X=y -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Hardware Sensors Chip support -# -CONFIG_I2C_SENSOR=y -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set - -# -# Other I2C Chip support -# -CONFIG_SENSORS_EEPROM=y -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Misc devices -# -# CONFIG_IBM_ASM is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set -# CONFIG_VIDEO_SELECT is not set - -# -# Console display driver support -# -CONFIG_VGA_CONSOLE=y -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -CONFIG_SND_HWDEP=y -CONFIG_SND_RAWMIDI=y -CONFIG_SND_SEQUENCER=y -# CONFIG_SND_SEQ_DUMMY is not set -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set - -# -# Generic devices -# -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_VIRMIDI is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# ISA devices -# -# CONFIG_SND_AD1848 is not set -# CONFIG_SND_CS4231 is not set -# CONFIG_SND_CS4232 is not set -# CONFIG_SND_CS4236 is not set -# CONFIG_SND_ES1688 is not set -# CONFIG_SND_ES18XX is not set -# CONFIG_SND_GUSCLASSIC is not set -# CONFIG_SND_GUSEXTREME is not set -# CONFIG_SND_GUSMAX is not set -# CONFIG_SND_INTERWAVE is not set -# CONFIG_SND_INTERWAVE_STB is not set -# CONFIG_SND_OPTI92X_AD1848 is not set -# CONFIG_SND_OPTI92X_CS4231 is not set -# CONFIG_SND_OPTI93X is not set -# CONFIG_SND_SB8 is not set -# CONFIG_SND_SB16 is not set -# CONFIG_SND_SBAWE is not set -# CONFIG_SND_WAVEFRONT is not set -# CONFIG_SND_CMI8330 is not set -# CONFIG_SND_OPL3SA2 is not set -# CONFIG_SND_SGALAXY is not set -# CONFIG_SND_SSCAPE is not set - -# -# PCI devices -# -CONFIG_SND_AC97_CODEC=y -# CONFIG_SND_ALI5451 is not set -# CONFIG_SND_ATIIXP is not set -# CONFIG_SND_ATIIXP_MODEM is not set -# CONFIG_SND_AU8810 is not set -# CONFIG_SND_AU8820 is not set -# CONFIG_SND_AU8830 is not set -# CONFIG_SND_AZT3328 is not set -# CONFIG_SND_BT87X is not set -# CONFIG_SND_CS46XX is not set -# CONFIG_SND_CS4281 is not set -CONFIG_SND_EMU10K1=y -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set -# CONFIG_SND_HDSP is not set -# CONFIG_SND_TRIDENT is not set -# CONFIG_SND_YMFPCI is not set -# CONFIG_SND_ALS4000 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_ENS1370 is not set -# CONFIG_SND_ENS1371 is not set -# CONFIG_SND_ES1938 is not set -# CONFIG_SND_ES1968 is not set -# CONFIG_SND_MAESTRO3 is not set -# CONFIG_SND_FM801 is not set -# CONFIG_SND_ICE1712 is not set -# CONFIG_SND_ICE1724 is not set -# CONFIG_SND_INTEL8X0 is not set -# CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_VIA82XX is not set -# CONFIG_SND_VX222 is not set - -# -# USB devices -# -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_USX2Y is not set - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set - -# -# USB support -# -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set -# CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y - -# -# USB Host Controller Drivers -# -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_OHCI_HCD is not set -CONFIG_USB_UHCI_HCD=y - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH_TTY is not set -# CONFIG_USB_MIDI is not set -# CONFIG_USB_ACM is not set -CONFIG_USB_PRINTER=y -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_RW_DETECT is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT=y -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -CONFIG_USB_EGALAX=m -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# -# CONFIG_USB_DABUSB is not set - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_TIGL is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -CONFIG_USB_CYTHERM=m -# CONFIG_USB_PHIDGETKIT is not set -CONFIG_USB_PHIDGETSERVO=m -# CONFIG_USB_TEST is not set - -# -# USB ATM/DSL drivers -# -# CONFIG_USB_ATM is not set -# CONFIG_USB_SPEEDTOUCH is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=y - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -CONFIG_UDF_FS=y -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set -CONFIG_NFSD_TCP=y -CONFIG_LOCKD=y -CONFIG_EXPORTFS=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Profiling support -# -CONFIG_PROFILING=y -CONFIG_OPROFILE=y - -# -# Kernel hacking -# -CONFIG_DEBUG_KERNEL=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_SCHEDSTATS is not set -CONFIG_DEBUG_SLAB=y -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_INFO is not set -CONFIG_FRAME_POINTER=y -CONFIG_EARLY_PRINTK=y -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_KPROBES is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_4KSTACKS is not set -CONFIG_X86_FIND_SMP_CONFIG=y -CONFIG_X86_MPPARSE=y - -# -# Security options -# -# CONFIG_KEYS is not set -CONFIG_SECURITY=y -CONFIG_SECURITY_NETWORK=y -CONFIG_SECURITY_CAPABILITIES=m -CONFIG_SECURITY_ROOTPLUG=m -# CONFIG_SECURITY_SECLVL is not set -CONFIG_SECURITY_SELINUX=y -# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set -CONFIG_SECURITY_SELINUX_DISABLE=y -CONFIG_SECURITY_SELINUX_DEVELOP=y -# CONFIG_SECURITY_SELINUX_MLS is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_WP512=y -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_BLOWFISH=y -CONFIG_CRYPTO_TWOFISH=y -CONFIG_CRYPTO_SERPENT=y -CONFIG_CRYPTO_AES_586=y -CONFIG_CRYPTO_CAST5=y -CONFIG_CRYPTO_CAST6=y -CONFIG_CRYPTO_TEA=y -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_KHAZAD=y -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_MICHAEL_MIC=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_TEST=y - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -CONFIG_CRC32=y -CONFIG_LIBCRC32C=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_X86_SMP=y -CONFIG_X86_HT=y -CONFIG_X86_BIOS_REBOOT=y -CONFIG_X86_TRAMPOLINE=y -CONFIG_PC=y diff --git a/testsuite/iproute2/Makefile b/testsuite/iproute2/Makefile deleted file mode 100644 index ba128aa..0000000 --- a/testsuite/iproute2/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -SUBDIRS := $(filter-out Makefile,$(wildcard *)) -.PHONY: all configure clean distclean show $(SUBDIRS) - -all: configure - @for dir in $(SUBDIRS); do \ - echo "Entering $$dir" && cd $$dir && $(MAKE) && cd ..; \ - done - -link: - @if [ ! -L iproute2-this ]; then \ - ln -s ../.. iproute2-this; \ - fi - -configure: link - @for dir in $(SUBDIRS); do \ - echo "Entering $$dir" && cd $$dir && if [ -f configure ]; then ./configure; fi && cd ..; \ - done - -clean: link - @for dir in $(SUBDIRS); do \ - echo "Entering $$dir" && cd $$dir && $(MAKE) clean && cd ..; \ - done - -distclean: clean - @for dir in $(SUBDIRS); do \ - echo "Entering $$dir" && cd $$dir && $(MAKE) distclean && cd ..; \ - done - -show: link - @echo "$(SUBDIRS)" - -$(SUBDIRS): - cd $@ && $(MAKE) diff --git a/testsuite/lib/generic.sh b/testsuite/lib/generic.sh deleted file mode 100644 index cc48947..0000000 --- a/testsuite/lib/generic.sh +++ /dev/null @@ -1,88 +0,0 @@ - -export DEST="127.0.0.1" - -ts_log() -{ - echo "$@" -} - -ts_err() -{ - ts_log "$@" | tee >> $ERRF -} - -ts_cat() -{ - cat "$@" -} - -ts_err_cat() -{ - ts_cat "$@" | tee >> $ERRF -} - -ts_tc() -{ - SCRIPT=$1; shift - DESC=$1; shift - TMP_ERR=`mktemp /tmp/tc_testsuite.XXXXXX` || exit - TMP_OUT=`mktemp /tmp/tc_testsuite.XXXXXX` || exit - - $TC $@ 2> $TMP_ERR > $TMP_OUT - - if [ -s $TMP_ERR ]; then - ts_err "${SCRIPT}: ${DESC} failed:" - ts_err "command: $TC $@" - ts_err "stderr output:" - ts_err_cat $TMP_ERR - if [ -s $TMP_OUT ]; then - ts_err "stdout output:" - ts_err_cat $TMP_OUT - fi - elif [ -s $TMP_OUT ]; then - echo "${SCRIPT}: ${DESC} succeeded with output:" - cat $TMP_OUT - else - echo "${SCRIPT}: ${DESC} succeeded" - fi - - rm $TMP_ERR $TMP_OUT -} - -ts_ip() -{ - SCRIPT=$1; shift - DESC=$1; shift - TMP_ERR=`mktemp /tmp/tc_testsuite.XXXXXX` || exit - TMP_OUT=`mktemp /tmp/tc_testsuite.XXXXXX` || exit - - $IP $@ 2> $TMP_ERR > $TMP_OUT - - if [ -s $TMP_ERR ]; then - ts_err "${SCRIPT}: ${DESC} failed:" - ts_err "command: $IP $@" - ts_err "stderr output:" - ts_err_cat $TMP_ERR - if [ -s $TMP_OUT ]; then - ts_err "stdout output:" - ts_err_cat $TMP_OUT - fi - elif [ -s $TMP_OUT ]; then - echo "${SCRIPT}: ${DESC} succeeded with output:" - cat $TMP_OUT - else - echo "${SCRIPT}: ${DESC} succeeded" - fi - - rm $TMP_ERR $TMP_OUT -} - -ts_qdisc_available() -{ - HELPOUT=`$TC qdisc add $1 help 2>&1` - if [ "`echo $HELPOUT | grep \"^Unknown qdisc\"`" ]; then - return 0; - else - return 1; - fi -} diff --git a/testsuite/tests/cbq.t b/testsuite/tests/cbq.t deleted file mode 100644 index bff814b..0000000 --- a/testsuite/tests/cbq.t +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -$TC qdisc del dev $DEV root >/dev/null 2>&1 -$TC qdisc add dev $DEV root handle 10:0 cbq bandwidth 100Mbit avpkt 1400 mpu 64 -$TC class add dev $DEV parent 10:0 classid 10:12 cbq bandwidth 100mbit rate 100mbit allot 1514 prio 3 maxburst 1 avpkt 500 bounded -$TC qdisc list dev $DEV -$TC qdisc del dev $DEV root -$TC qdisc list dev $DEV -$TC qdisc add dev $DEV root handle 10:0 cbq bandwidth 100Mbit avpkt 1400 mpu 64 -$TC class add dev $DEV parent 10:0 classid 10:12 cbq bandwidth 100mbit rate 100mbit allot 1514 prio 3 maxburst 1 avpkt 500 bounded -$TC qdisc del dev $DEV root diff --git a/testsuite/tests/cls-testbed.t b/testsuite/tests/cls-testbed.t deleted file mode 100644 index efae2a5..0000000 --- a/testsuite/tests/cls-testbed.t +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -# vim: ft=sh - -source lib/generic.sh - -QDISCS="cbq htb dsmark" - -for q in ${QDISCS}; do - ts_log "Preparing classifier testbed with qdisc $q" - - for c in tests/cls/*.t; do - - case "$q" in - cbq) - ts_tc "cls-testbed" "cbq root qdisc creation" \ - qdisc add dev $DEV root handle 10:0 \ - cbq bandwidth 100Mbit avpkt 1400 mpu 64 - ts_tc "cls-testbed" "cbq root class creation" \ - class add dev $DEV parent 10:0 classid 10:12 \ - cbq bandwidth 100mbit rate 100mbit allot 1514 prio 3 \ - maxburst 1 avpkt 500 bounded - ;; - htb) - ts_qdisc_available "htb" - if [ $? -eq 0 ]; then - ts_log "cls-testbed: HTB is unsupported by $TC, skipping" - continue; - fi - ts_tc "cls-testbed" "htb root qdisc creation" \ - qdisc add dev $DEV root handle 10:0 htb - ts_tc "cls-testbed" "htb root class creation" \ - class add dev $DEV parent 10:0 classid 10:12 \ - htb rate 100Mbit quantum 1514 - ;; - dsmark) - ts_qdisc_available "dsmark" - if [ $? -eq 0 ]; then - ts_log "cls-testbed: dsmark is unsupported by $TC, skipping" - continue; - fi - ts_tc "cls-testbed" "dsmark root qdisc creation" \ - qdisc add dev $DEV root handle 20:0 \ - dsmark indices 64 default_index 1 set_tc_index - ts_tc "cls-testbed" "dsmark class creation" \ - class change dev $DEV parent 20:0 classid 20:12 \ - dsmark mask 0xff value 2 - ts_tc "cls-testbed" "prio inner qdisc creation" \ - qdisc add dev $DEV parent 20:0 handle 10:0 prio - ;; - *) - ts_err "cls-testbed: no testbed configuration found for qdisc $q" - continue - ;; - esac - - ts_tc "cls-testbed" "tree listing" qdisc list dev eth0 - ts_tc "cls-testbed" "tree class listing" class list dev eth0 - ts_log "cls-testbed: starting classifier test $c" - $c - - case "$q" in - *) - ts_tc "cls-testbed" "generic qdisc tree deletion" \ - qdisc del dev $DEV root - ;; - esac - done -done diff --git a/testsuite/tests/dsmark.t b/testsuite/tests/dsmark.t deleted file mode 100644 index 6934165..0000000 --- a/testsuite/tests/dsmark.t +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -# vim: ft=sh - -source lib/generic.sh - -ts_qdisc_available "dsmark" -if [ $? -eq 0 ]; then - ts_log "dsmark: Unsupported by $TC, skipping" - exit 127 -fi - -ts_tc "dsmark" "dsmark root qdisc creation" \ - qdisc add dev $DEV root handle 10:0 \ - dsmark indices 64 default_index 1 set_tc_index - -ts_tc "dsmark" "dsmark class 1 creation" \ - class change dev $DEV parent 10:0 classid 10:12 \ - dsmark mask 0xff value 2 - -ts_tc "dsmark" "dsmark class 2 creation" \ - class change dev $DEV parent 10:0 classid 10:13 \ - dsmark mask 0xfc value 4 - -ts_tc "dsmark" "dsmark dump qdisc" \ - qdisc list dev $DEV - -ts_tc "dsmark" "dsmark dump class" \ - class list dev $DEV parent 10:0 - -ts_tc "dsmark" "generic qdisc tree deletion" \ - qdisc del dev $DEV root diff --git a/testsuite/tests/policer b/testsuite/tests/policer deleted file mode 100644 index eaf16ac..0000000 --- a/testsuite/tests/policer +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -$TC qdisc del dev $DEV root >/dev/null 2>&1 -$TC qdisc add dev $DEV root handle 10:0 cbq bandwidth 100Mbit avpkt 1400 mpu 64 -$TC class add dev $DEV parent 10:0 classid 10:12 cbq bandwidth 100mbit rate 100mbit allot 1514 prio 3 maxburst 1 avpkt 500 bounded -$TC filter add dev $DEV parent 10:0 protocol ip prio 10 u32 match ip protocol 1 0xff police rate 2kbit buffer 10k drop flowid 10:12 -$TC qdisc list dev $DEV -$TC filter list dev $DEV parent 10:0 -$TC qdisc del dev $DEV root -$TC qdisc list dev $DEV -$TC qdisc add dev $DEV root handle 10:0 cbq bandwidth 100Mbit avpkt 1400 mpu 64 -$TC class add dev $DEV parent 10:0 classid 10:12 cbq bandwidth 100mbit rate 100mbit allot 1514 prio 3 maxburst 1 avpkt 500 bounded -$TC filter add dev $DEV parent 10:0 protocol ip prio 10 u32 match ip protocol 1 0xff police rate 2kbit buffer 10k drop flowid 10:12 -$TC qdisc del dev $DEV root -- 2.43.0