From 4067b6e905e5507d2c22fd464480a3361ab001bf Mon Sep 17 00:00:00 2001 From: fengbojiang Date: Thu, 30 Sep 2021 19:34:02 +0800 Subject: [PATCH] ff tools upgrade to support FreeBSD 13.0. --- tools/README.md | 22 +- tools/arp/Makefile | 10 +- tools/arp/arp.c | 53 + tools/compat/compat.h | 2 + tools/compat/fnmatch.c | 238 + tools/compat/getaddrinfo.c | 1 + tools/compat/include/alias.h | 25 +- tools/compat/include/net/bpf.h | 1065 +- tools/compat/include/net/bpfdesc.h | 35 +- tools/compat/include/net/dlt.h | 1412 +++ tools/compat/include/net/ethernet.h | 99 +- tools/compat/include/net/flowtable.h | 56 - tools/compat/include/net/if.h | 106 +- tools/compat/include/net/if_arp.h | 25 +- tools/compat/include/net/if_bridgevar.h | 54 + tools/compat/include/net/if_dl.h | 8 +- tools/compat/include/net/if_gif.h | 87 + tools/compat/include/net/if_gre.h | 134 +- tools/compat/include/net/if_pfsync.h | 24 +- tools/compat/include/net/if_types.h | 7 +- tools/compat/include/net/if_vlan_var.h | 105 +- tools/compat/include/net/if_vxlan.h | 25 +- tools/compat/include/net/iso88025.h | 180 - tools/compat/include/net/netisr.h | 3 +- tools/compat/include/net/netisr_internal.h | 2 + tools/compat/include/net/pfvar.h | 507 +- tools/compat/include/net/radix.h | 51 +- tools/compat/include/net/route.h | 261 +- tools/compat/include/net/route/nhop.h | 245 + tools/compat/include/netinet/icmp6.h | 27 +- tools/compat/include/netinet/icmp_var.h | 7 +- tools/compat/include/netinet/if_ether.h | 20 +- tools/compat/include/netinet/igmp.h | 4 +- tools/compat/include/netinet/igmp_var.h | 16 +- tools/compat/include/netinet/in.h | 38 +- tools/compat/include/netinet/in_pcb.h | 428 +- tools/compat/include/netinet/in_systm.h | 9 +- tools/compat/include/netinet/in_var.h | 438 +- tools/compat/include/netinet/ip.h | 9 +- tools/compat/include/netinet/ip_carp.h | 45 +- tools/compat/include/netinet/ip_fw.h | 88 +- tools/compat/include/netinet/ip_icmp.h | 4 +- tools/compat/include/netinet/ip_mroute.h | 5 +- tools/compat/include/netinet/ip_var.h | 33 +- tools/compat/include/netinet/pim_var.h | 4 +- tools/compat/include/netinet/sctp.h | 20 +- tools/compat/include/netinet/sctp_constants.h | 117 +- tools/compat/include/netinet/sctp_uio.h | 112 +- tools/compat/include/netinet/tcp.h | 164 +- tools/compat/include/netinet/tcp_fsm.h | 9 +- tools/compat/include/netinet/tcp_seq.h | 19 +- tools/compat/include/netinet/tcp_timer.h | 46 +- tools/compat/include/netinet/tcp_var.h | 825 +- tools/compat/include/netinet/tcpip.h | 4 +- tools/compat/include/netinet/udp.h | 8 +- tools/compat/include/netinet/udp_var.h | 12 +- tools/compat/include/netinet6/in6.h | 32 +- tools/compat/include/netinet6/in6_pcb.h | 14 +- tools/compat/include/netinet6/in6_var.h | 189 +- tools/compat/include/netinet6/ip6_mroute.h | 2 + tools/compat/include/netinet6/ip6_var.h | 68 +- tools/compat/include/netinet6/ip_fw_nat64.h | 210 + tools/compat/include/netinet6/ip_fw_nptv6.h | 54 + tools/compat/include/netinet6/nd6.h | 137 +- tools/compat/include/netinet6/pim6_var.h | 6 +- tools/compat/include/netinet6/raw_ip6.h | 2 + tools/compat/include/sys/_domainset.h | 60 + tools/compat/include/sys/_smr.h | 50 + tools/compat/include/sys/_types.h | 5 + tools/compat/include/sys/ck.h | 13 + tools/compat/include/sys/epoch.h | 112 + tools/compat/include/sys/sf_buf.h | 19 +- tools/compat/include/sys/socket.h | 148 +- tools/compat/include/sys/sockio.h | 24 +- tools/compat/include/sys/unpcb.h | 136 +- tools/compat/include/vm/uma.h | 247 +- tools/compat/include/vm/uma_int.h | 583 +- tools/ifconfig/Makefile | 72 +- tools/ifconfig/af_inet.c | 27 +- tools/ifconfig/af_inet6.c | 73 +- tools/ifconfig/af_link.c | 8 + tools/ifconfig/af_nd6.c | 25 + tools/ifconfig/carp.c | 30 + tools/ifconfig/ifbridge.c | 17 + tools/ifconfig/ifclone.c | 45 + tools/ifconfig/ifconfig.c | 134 +- tools/ifconfig/ifconfig.h | 15 + tools/ifconfig/ifgif.c | 16 + tools/ifconfig/ifgre.c | 38 + tools/ifconfig/ifgroup.c | 27 + tools/ifconfig/ifipsec.c | 13 + tools/ifconfig/iflagg.c | 8 +- tools/ifconfig/ifvlan.c | 29 + tools/ifconfig/ifvxlan.c | 29 + tools/ipfw/Makefile | 26 +- tools/ipfw/compat.c | 128 + tools/ipfw/dummynet.c | 8 +- tools/ipfw/ipfw2.c | 40 +- tools/ipfw/ipfw2.h | 12 + tools/ipfw/ipv6.c | 18 +- tools/ipfw/main.c | 52 +- tools/ipfw/nat.c | 11 + tools/ipfw/nat64clat.c | 6 + tools/ipfw/nat64lsn.c | 6 + tools/ipfw/nat64stl.c | 6 + tools/ipfw/nptv6.c | 5 + tools/ipfw/tables.c | 23 +- tools/libmemstat/Makefile | 5 +- tools/libmemstat/memstat.c | 4 + tools/libmemstat/memstat_all.c | 7 + tools/libmemstat/memstat_malloc.c | 13 + tools/libmemstat/memstat_uma.c | 11 + tools/libnetgraph/Makefile | 18 +- tools/libnetgraph/compat.c | 235 + tools/libnetgraph/internal.h | 11 + tools/libnetgraph/msg.c | 36 + tools/libnetgraph/netgraph.h | 24 + tools/libnetgraph/sock.c | 9 + tools/libutil/Makefile | 21 +- tools/libutil/fparseln.c | 11 + tools/libutil/libutil.h | 4 + tools/libutil/stub.c | 6 + tools/libxo/.gitignore | 46 + tools/libxo/.svnignore | 18 + tools/libxo/.travis.yml | 12 + tools/libxo/Copyright | 23 + tools/libxo/INSTALL.md | 15 + tools/libxo/LICENSE | 23 + tools/libxo/Makefile | 25 +- tools/libxo/Makefile.am | 144 + tools/libxo/Makefile.depend | 17 - tools/libxo/README.md | 67 + tools/libxo/configure.ac | 500 + tools/libxo/doc/Makefile.am | 29 + tools/libxo/doc/_static/basic.css_t | 657 ++ tools/libxo/doc/_templates/localtoc.html | 14 + tools/libxo/doc/api.rst | 1679 +++ tools/libxo/doc/conf.py | 186 + tools/libxo/doc/encoders.rst | 274 + tools/libxo/doc/example.rst | 694 ++ tools/libxo/doc/faq.rst | 208 + tools/libxo/doc/field-formatting.rst | 370 + tools/libxo/doc/field-modifiers.rst | 353 + tools/libxo/doc/field-roles.rst | 312 + tools/libxo/doc/format-strings.rst | 47 + tools/libxo/doc/formatting.rst | 165 + tools/libxo/doc/getting.rst | 185 + tools/libxo/doc/howto.rst | 394 + tools/libxo/doc/index.rst | 54 + tools/libxo/doc/intro.rst | 90 + tools/libxo/doc/options.rst | 184 + tools/libxo/doc/top-link.html.in | 9 + tools/libxo/doc/xo.rst | 234 + tools/libxo/doc/xohtml.rst | 30 + tools/libxo/doc/xolint.rst | 444 + tools/libxo/doc/xopo.rst | 45 + tools/libxo/encoder/Makefile | 13 - tools/libxo/encoder/Makefile.am | 12 + tools/libxo/encoder/cbor/Makefile.am | 51 + tools/libxo/encoder/cbor/enc_cbor.c | 366 + tools/libxo/encoder/csv/Makefile | 24 - tools/libxo/encoder/csv/Makefile.am | 51 + tools/libxo/encoder/csv/enc_csv.c | 834 ++ tools/libxo/encoder/test/Makefile.am | 51 + tools/libxo/encoder/test/enc_test.c | 30 + tools/libxo/libxo-config.in | 119 + tools/libxo/libxo/Makefile | 114 - tools/libxo/libxo/Makefile.am | 95 + tools/libxo/{add.man => libxo/add.man.in} | 5 +- tools/libxo/libxo/gen-wide.sh | 76 + tools/libxo/libxo/libxo.3 | 323 + tools/libxo/libxo/libxo.c | 8518 +++++++++++++++ tools/libxo/libxo/xo.h | 702 ++ tools/libxo/libxo/xo_attr.3 | 70 + tools/libxo/libxo/xo_buf.h | 163 + tools/libxo/libxo/xo_create.3 | 77 + tools/libxo/libxo/xo_emit.3 | 114 + tools/libxo/libxo/xo_emit_err.3 | 82 + tools/libxo/libxo/xo_emit_f.3 | 121 + tools/libxo/libxo/xo_encoder.c | 417 + tools/libxo/libxo/xo_encoder.h | 170 + tools/libxo/libxo/xo_err.3 | 84 + tools/libxo/libxo/xo_error.3 | 51 + tools/libxo/libxo/xo_explicit.h | 61 + tools/libxo/libxo/xo_finish.3 | 49 + tools/libxo/libxo/xo_flush.3 | 45 + tools/libxo/libxo/xo_format.5 | 977 ++ tools/libxo/libxo/xo_humanize.h | 169 + tools/libxo/libxo/xo_message.3 | 78 + tools/libxo/libxo/xo_no_setlocale.3 | 53 + tools/libxo/libxo/xo_open_container.3 | 198 + tools/libxo/libxo/xo_open_list.3 | 168 + tools/libxo/libxo/xo_open_marker.3 | 115 + tools/libxo/libxo/xo_options.7 | 156 + tools/libxo/libxo/xo_parse_args.3 | 162 + tools/libxo/libxo/xo_set_allocator.3 | 64 + tools/libxo/libxo/xo_set_flags.3 | 149 + tools/libxo/libxo/xo_set_info.3 | 112 + tools/libxo/libxo/xo_set_options.3 | 41 + tools/libxo/libxo/xo_set_style.3 | 63 + .../libxo/libxo/xo_set_syslog_enterprise_id.3 | 46 + tools/libxo/libxo/xo_set_version.3 | 44 + tools/libxo/libxo/xo_set_writer.3 | 66 + tools/libxo/libxo/xo_syslog.3 | 89 + tools/libxo/libxo/xo_syslog.c | 711 ++ tools/libxo/libxo/xo_wcwidth.h | 313 + tools/libxo/packaging/libxo.pc.in | 11 + tools/libxo/packaging/libxo.rb.base.in | 20 + tools/libxo/packaging/libxo.spec.in | 44 + tools/libxo/tests/Makefile | 251 - tools/libxo/tests/Makefile.am | 32 + tools/libxo/tests/Makefile.depend | 19 - tools/libxo/tests/core/Makefile.am | 148 + tools/libxo/tests/core/saved/test_01.E.err | 0 tools/libxo/tests/core/saved/test_01.E.out | 202 + .../libxo/tests/core/saved/test_01.Ecsv1.err | 0 .../libxo/tests/core/saved/test_01.Ecsv1.out | 17 + .../libxo/tests/core/saved/test_01.Ecsv2.err | 0 .../libxo/tests/core/saved/test_01.Ecsv2.out | 10 + .../libxo/tests/core/saved/test_01.Ecsv3.err | 0 .../libxo/tests/core/saved/test_01.Ecsv3.out | 17 + tools/libxo/tests/core/saved/test_01.H.err | 0 tools/libxo/tests/core/saved/test_01.H.out | 2 + tools/libxo/tests/core/saved/test_01.HIPx.err | 0 tools/libxo/tests/core/saved/test_01.HIPx.out | 434 + tools/libxo/tests/core/saved/test_01.HP.err | 0 tools/libxo/tests/core/saved/test_01.HP.out | 434 + tools/libxo/tests/core/saved/test_01.J.err | 0 tools/libxo/tests/core/saved/test_01.J.out | 1 + tools/libxo/tests/core/saved/test_01.JP.err | 0 tools/libxo/tests/core/saved/test_01.JP.out | 182 + tools/libxo/tests/core/saved/test_01.T.err | 0 tools/libxo/tests/core/saved/test_01.T.out | 66 + tools/libxo/tests/core/saved/test_01.X.err | 0 tools/libxo/tests/core/saved/test_01.X.out | 1 + tools/libxo/tests/core/saved/test_01.XP.err | 0 tools/libxo/tests/core/saved/test_01.XP.out | 170 + tools/libxo/tests/core/saved/test_01.err | 0 tools/libxo/tests/core/saved/test_01.out | 38 + tools/libxo/tests/core/saved/test_02.E.err | 1 + tools/libxo/tests/core/saved/test_02.E.out | 72 + tools/libxo/tests/core/saved/test_02.H.err | 1 + tools/libxo/tests/core/saved/test_02.H.out | 10 + tools/libxo/tests/core/saved/test_02.HIPx.err | 1 + tools/libxo/tests/core/saved/test_02.HIPx.out | 242 + tools/libxo/tests/core/saved/test_02.HP.err | 1 + tools/libxo/tests/core/saved/test_02.HP.out | 242 + tools/libxo/tests/core/saved/test_02.J.err | 1 + tools/libxo/tests/core/saved/test_02.J.out | 1 + tools/libxo/tests/core/saved/test_02.JP.err | 1 + tools/libxo/tests/core/saved/test_02.JP.out | 98 + tools/libxo/tests/core/saved/test_02.T.err | 5 + tools/libxo/tests/core/saved/test_02.T.out | 37 + tools/libxo/tests/core/saved/test_02.X.err | 1 + tools/libxo/tests/core/saved/test_02.X.out | 10 + tools/libxo/tests/core/saved/test_02.XP.err | 1 + tools/libxo/tests/core/saved/test_02.XP.out | 106 + tools/libxo/tests/core/saved/test_02.err | 0 tools/libxo/tests/core/saved/test_02.out | 38 + tools/libxo/tests/core/saved/test_03.E.err | 0 tools/libxo/tests/core/saved/test_03.E.out | 34 + tools/libxo/tests/core/saved/test_03.H.err | 0 tools/libxo/tests/core/saved/test_03.H.out | 1 + tools/libxo/tests/core/saved/test_03.HIPx.err | 0 tools/libxo/tests/core/saved/test_03.HIPx.out | 55 + tools/libxo/tests/core/saved/test_03.HP.err | 0 tools/libxo/tests/core/saved/test_03.HP.out | 55 + tools/libxo/tests/core/saved/test_03.J.err | 0 tools/libxo/tests/core/saved/test_03.J.out | 1 + tools/libxo/tests/core/saved/test_03.JP.err | 0 tools/libxo/tests/core/saved/test_03.JP.out | 33 + tools/libxo/tests/core/saved/test_03.T.err | 0 tools/libxo/tests/core/saved/test_03.T.out | 7 + tools/libxo/tests/core/saved/test_03.X.err | 0 tools/libxo/tests/core/saved/test_03.X.out | 1 + tools/libxo/tests/core/saved/test_03.XP.err | 0 tools/libxo/tests/core/saved/test_03.XP.out | 25 + tools/libxo/tests/core/saved/test_03.err | 0 tools/libxo/tests/core/saved/test_03.out | 3 + tools/libxo/tests/core/saved/test_04.E.err | 0 tools/libxo/tests/core/saved/test_04.E.out | 22 + tools/libxo/tests/core/saved/test_04.H.err | 0 tools/libxo/tests/core/saved/test_04.H.out | 1 + tools/libxo/tests/core/saved/test_04.HIPx.err | 0 tools/libxo/tests/core/saved/test_04.HIPx.out | 20 + tools/libxo/tests/core/saved/test_04.HP.err | 0 tools/libxo/tests/core/saved/test_04.HP.out | 20 + tools/libxo/tests/core/saved/test_04.J.err | 0 tools/libxo/tests/core/saved/test_04.J.out | 1 + tools/libxo/tests/core/saved/test_04.JP.err | 0 tools/libxo/tests/core/saved/test_04.JP.out | 21 + tools/libxo/tests/core/saved/test_04.T.err | 0 tools/libxo/tests/core/saved/test_04.T.out | 4 + tools/libxo/tests/core/saved/test_04.X.err | 0 tools/libxo/tests/core/saved/test_04.X.out | 1 + tools/libxo/tests/core/saved/test_04.XP.err | 0 tools/libxo/tests/core/saved/test_04.XP.out | 17 + tools/libxo/tests/core/saved/test_05.E.err | 0 tools/libxo/tests/core/saved/test_05.E.out | 96 + tools/libxo/tests/core/saved/test_05.H.err | 0 tools/libxo/tests/core/saved/test_05.H.out | 1 + tools/libxo/tests/core/saved/test_05.HIPx.err | 0 tools/libxo/tests/core/saved/test_05.HIPx.out | 212 + tools/libxo/tests/core/saved/test_05.HP.err | 0 tools/libxo/tests/core/saved/test_05.HP.out | 212 + tools/libxo/tests/core/saved/test_05.J.err | 0 tools/libxo/tests/core/saved/test_05.J.out | 1 + tools/libxo/tests/core/saved/test_05.JP.err | 0 tools/libxo/tests/core/saved/test_05.JP.out | 91 + tools/libxo/tests/core/saved/test_05.T.err | 0 tools/libxo/tests/core/saved/test_05.T.out | 39 + tools/libxo/tests/core/saved/test_05.X.err | 0 tools/libxo/tests/core/saved/test_05.X.out | 1 + tools/libxo/tests/core/saved/test_05.XP.err | 0 tools/libxo/tests/core/saved/test_05.XP.out | 85 + tools/libxo/tests/core/saved/test_06.E.err | 0 tools/libxo/tests/core/saved/test_06.E.out | 22 + tools/libxo/tests/core/saved/test_06.H.err | 0 tools/libxo/tests/core/saved/test_06.H.out | 1 + tools/libxo/tests/core/saved/test_06.HIPx.err | 0 tools/libxo/tests/core/saved/test_06.HIPx.out | 21 + tools/libxo/tests/core/saved/test_06.HP.err | 0 tools/libxo/tests/core/saved/test_06.HP.out | 21 + tools/libxo/tests/core/saved/test_06.J.err | 0 tools/libxo/tests/core/saved/test_06.J.out | 1 + tools/libxo/tests/core/saved/test_06.JP.err | 0 tools/libxo/tests/core/saved/test_06.JP.out | 21 + tools/libxo/tests/core/saved/test_06.T.err | 0 tools/libxo/tests/core/saved/test_06.T.out | 3 + tools/libxo/tests/core/saved/test_06.X.err | 0 tools/libxo/tests/core/saved/test_06.X.out | 1 + tools/libxo/tests/core/saved/test_06.XP.err | 0 tools/libxo/tests/core/saved/test_06.XP.out | 17 + tools/libxo/tests/core/saved/test_07.E.err | 0 tools/libxo/tests/core/saved/test_07.E.out | 76 + tools/libxo/tests/core/saved/test_07.H.err | 0 tools/libxo/tests/core/saved/test_07.H.out | 1 + tools/libxo/tests/core/saved/test_07.HIPx.err | 0 tools/libxo/tests/core/saved/test_07.HIPx.out | 107 + tools/libxo/tests/core/saved/test_07.HP.err | 0 tools/libxo/tests/core/saved/test_07.HP.out | 107 + tools/libxo/tests/core/saved/test_07.J.err | 0 tools/libxo/tests/core/saved/test_07.J.out | 1 + tools/libxo/tests/core/saved/test_07.JP.err | 0 tools/libxo/tests/core/saved/test_07.JP.out | 71 + tools/libxo/tests/core/saved/test_07.T.err | 0 tools/libxo/tests/core/saved/test_07.T.out | 19 + tools/libxo/tests/core/saved/test_07.X.err | 0 tools/libxo/tests/core/saved/test_07.X.out | 1 + tools/libxo/tests/core/saved/test_07.XP.err | 0 tools/libxo/tests/core/saved/test_07.XP.out | 65 + tools/libxo/tests/core/saved/test_08.E.err | 18 + tools/libxo/tests/core/saved/test_08.E.out | 186 + tools/libxo/tests/core/saved/test_08.H.err | 18 + tools/libxo/tests/core/saved/test_08.H.out | 1 + tools/libxo/tests/core/saved/test_08.HIPx.err | 18 + tools/libxo/tests/core/saved/test_08.HIPx.out | 264 + tools/libxo/tests/core/saved/test_08.HP.err | 18 + tools/libxo/tests/core/saved/test_08.HP.out | 264 + tools/libxo/tests/core/saved/test_08.J.err | 18 + tools/libxo/tests/core/saved/test_08.J.out | 1 + tools/libxo/tests/core/saved/test_08.JP.err | 18 + tools/libxo/tests/core/saved/test_08.JP.out | 185 + tools/libxo/tests/core/saved/test_08.T.err | 18 + tools/libxo/tests/core/saved/test_08.T.out | 52 + tools/libxo/tests/core/saved/test_08.X.err | 18 + tools/libxo/tests/core/saved/test_08.X.out | 1 + tools/libxo/tests/core/saved/test_08.XP.err | 18 + tools/libxo/tests/core/saved/test_08.XP.out | 165 + tools/libxo/tests/core/saved/test_09.E.err | 0 tools/libxo/tests/core/saved/test_09.E.out | 40 + tools/libxo/tests/core/saved/test_09.H.err | 0 tools/libxo/tests/core/saved/test_09.H.out | 1 + tools/libxo/tests/core/saved/test_09.HIPx.err | 0 tools/libxo/tests/core/saved/test_09.HIPx.out | 93 + tools/libxo/tests/core/saved/test_09.HP.err | 0 tools/libxo/tests/core/saved/test_09.HP.out | 93 + tools/libxo/tests/core/saved/test_09.J.err | 0 tools/libxo/tests/core/saved/test_09.J.out | 1 + tools/libxo/tests/core/saved/test_09.JP.err | 0 tools/libxo/tests/core/saved/test_09.JP.out | 39 + tools/libxo/tests/core/saved/test_09.T.err | 0 tools/libxo/tests/core/saved/test_09.T.out | 25 + tools/libxo/tests/core/saved/test_09.X.err | 0 tools/libxo/tests/core/saved/test_09.X.out | 1 + tools/libxo/tests/core/saved/test_09.XP.err | 0 tools/libxo/tests/core/saved/test_09.XP.out | 29 + tools/libxo/tests/core/saved/test_10.E.err | 0 tools/libxo/tests/core/saved/test_10.E.out | 126 + tools/libxo/tests/core/saved/test_10.H.err | 0 tools/libxo/tests/core/saved/test_10.H.out | 1 + tools/libxo/tests/core/saved/test_10.HIPx.err | 0 tools/libxo/tests/core/saved/test_10.HIPx.out | 316 + tools/libxo/tests/core/saved/test_10.HP.err | 0 tools/libxo/tests/core/saved/test_10.HP.out | 316 + tools/libxo/tests/core/saved/test_10.J.err | 0 tools/libxo/tests/core/saved/test_10.J.out | 1 + tools/libxo/tests/core/saved/test_10.JP.err | 0 tools/libxo/tests/core/saved/test_10.JP.out | 113 + tools/libxo/tests/core/saved/test_10.T.err | 0 tools/libxo/tests/core/saved/test_10.T.out | 48 + tools/libxo/tests/core/saved/test_10.X.err | 0 tools/libxo/tests/core/saved/test_10.X.out | 1 + tools/libxo/tests/core/saved/test_10.XP.err | 0 tools/libxo/tests/core/saved/test_10.XP.out | 100 + tools/libxo/tests/core/saved/test_10.err | 0 tools/libxo/tests/core/saved/test_10.out | 38 + tools/libxo/tests/core/saved/test_11.E.err | 0 tools/libxo/tests/core/saved/test_11.E.out | 22 + tools/libxo/tests/core/saved/test_11.H.err | 0 tools/libxo/tests/core/saved/test_11.H.out | 16 + tools/libxo/tests/core/saved/test_11.HIPx.err | 0 tools/libxo/tests/core/saved/test_11.HIPx.out | 16 + tools/libxo/tests/core/saved/test_11.HP.err | 0 tools/libxo/tests/core/saved/test_11.HP.out | 16 + tools/libxo/tests/core/saved/test_11.J.err | 0 tools/libxo/tests/core/saved/test_11.J.out | 17 + tools/libxo/tests/core/saved/test_11.JP.err | 0 tools/libxo/tests/core/saved/test_11.JP.out | 22 + tools/libxo/tests/core/saved/test_11.T.err | 0 tools/libxo/tests/core/saved/test_11.T.out | 16 + tools/libxo/tests/core/saved/test_11.X.err | 0 tools/libxo/tests/core/saved/test_11.X.out | 17 + tools/libxo/tests/core/saved/test_11.XP.err | 0 tools/libxo/tests/core/saved/test_11.XP.out | 18 + tools/libxo/tests/core/saved/test_12.E.err | 4 + tools/libxo/tests/core/saved/test_12.E.out | 95 + tools/libxo/tests/core/saved/test_12.H.err | 4 + tools/libxo/tests/core/saved/test_12.H.out | 1 + tools/libxo/tests/core/saved/test_12.HIPx.err | 4 + tools/libxo/tests/core/saved/test_12.HIPx.out | 175 + tools/libxo/tests/core/saved/test_12.HP.err | 4 + tools/libxo/tests/core/saved/test_12.HP.out | 175 + tools/libxo/tests/core/saved/test_12.J.err | 4 + tools/libxo/tests/core/saved/test_12.J.out | 1 + tools/libxo/tests/core/saved/test_12.JP.err | 4 + tools/libxo/tests/core/saved/test_12.JP.out | 94 + tools/libxo/tests/core/saved/test_12.T.err | 4 + tools/libxo/tests/core/saved/test_12.T.out | 23 + tools/libxo/tests/core/saved/test_12.X.err | 4 + tools/libxo/tests/core/saved/test_12.X.out | 1 + tools/libxo/tests/core/saved/test_12.XP.err | 4 + tools/libxo/tests/core/saved/test_12.XP.out | 90 + tools/libxo/tests/core/test_01.c | 256 + tools/libxo/tests/core/test_02.c | 161 + tools/libxo/tests/core/test_03.c | 109 + tools/libxo/tests/core/test_04.c | 63 + tools/libxo/tests/core/test_05.c | 143 + tools/libxo/tests/core/test_06.c | 63 + tools/libxo/tests/core/test_07.c | 97 + tools/libxo/tests/core/test_08.c | 158 + tools/libxo/tests/core/test_09.c | 115 + tools/libxo/tests/core/test_10.c | 213 + tools/libxo/tests/core/test_11.c | 110 + tools/libxo/tests/core/test_12.c | 95 + tools/libxo/tests/encoder/Makefile | 21 - tools/libxo/tests/encoder/Makefile.depend | 17 - tools/libxo/tests/functional_test.sh | 76 - tools/libxo/tests/gettext/Makefile.am | 223 + tools/libxo/tests/gettext/gt_01.c | 116 + tools/libxo/tests/gettext/gt_01.pot | 105 + tools/libxo/tests/gettext/ldns.pot | 28 + .../libxo/tests/gettext/po/pig_latin/gt_01.po | 109 + .../libxo/tests/gettext/po/pig_latin/ldns.po | 30 + .../tests/gettext/po/pig_latin/strerror.po | 463 + tools/libxo/tests/gettext/saved/gt_01.H.err | 0 tools/libxo/tests/gettext/saved/gt_01.H.out | 1 + .../libxo/tests/gettext/saved/gt_01.HIPx.err | 0 .../libxo/tests/gettext/saved/gt_01.HIPx.out | 139 + tools/libxo/tests/gettext/saved/gt_01.HP.err | 0 tools/libxo/tests/gettext/saved/gt_01.HP.out | 139 + tools/libxo/tests/gettext/saved/gt_01.J.err | 0 tools/libxo/tests/gettext/saved/gt_01.J.out | 1 + tools/libxo/tests/gettext/saved/gt_01.JP.err | 0 tools/libxo/tests/gettext/saved/gt_01.JP.out | 53 + tools/libxo/tests/gettext/saved/gt_01.T.err | 0 tools/libxo/tests/gettext/saved/gt_01.T.out | 17 + tools/libxo/tests/gettext/saved/gt_01.X.err | 0 tools/libxo/tests/gettext/saved/gt_01.X.out | 1 + tools/libxo/tests/gettext/saved/gt_01.XP.err | 0 tools/libxo/tests/gettext/saved/gt_01.XP.out | 49 + tools/libxo/tests/gettext/strerror.pot | 472 + tools/libxo/tests/xo/Makefile.am | 83 + tools/libxo/tests/xo/saved/xo_01.H.err | 0 tools/libxo/tests/xo/saved/xo_01.H.out | 1 + tools/libxo/tests/xo/saved/xo_01.HIPx.err | 0 tools/libxo/tests/xo/saved/xo_01.HIPx.out | 80 + tools/libxo/tests/xo/saved/xo_01.HP.err | 0 tools/libxo/tests/xo/saved/xo_01.HP.out | 80 + tools/libxo/tests/xo/saved/xo_01.J.err | 0 tools/libxo/tests/xo/saved/xo_01.J.out | 1 + tools/libxo/tests/xo/saved/xo_01.JP.err | 0 tools/libxo/tests/xo/saved/xo_01.JP.out | 38 + tools/libxo/tests/xo/saved/xo_01.T.err | 0 tools/libxo/tests/xo/saved/xo_01.T.out | 9 + tools/libxo/tests/xo/saved/xo_01.X.err | 0 tools/libxo/tests/xo/saved/xo_01.X.out | 1 + tools/libxo/tests/xo/saved/xo_01.XP.err | 0 tools/libxo/tests/xo/saved/xo_01.XP.out | 38 + tools/libxo/tests/xo/saved/xo_02.H.err | 26 + tools/libxo/tests/xo/saved/xo_02.H.out | 1 + tools/libxo/tests/xo/saved/xo_02.HIPx.err | 26 + tools/libxo/tests/xo/saved/xo_02.HIPx.out | 83 + tools/libxo/tests/xo/saved/xo_02.HP.err | 26 + tools/libxo/tests/xo/saved/xo_02.HP.out | 83 + tools/libxo/tests/xo/saved/xo_02.J.err | 26 + tools/libxo/tests/xo/saved/xo_02.J.out | 7 + tools/libxo/tests/xo/saved/xo_02.JP.err | 26 + tools/libxo/tests/xo/saved/xo_02.JP.out | 84 + tools/libxo/tests/xo/saved/xo_02.T.err | 26 + tools/libxo/tests/xo/saved/xo_02.T.out | 14 + tools/libxo/tests/xo/saved/xo_02.X.err | 26 + tools/libxo/tests/xo/saved/xo_02.X.out | 1 + tools/libxo/tests/xo/saved/xo_02.XP.err | 26 + tools/libxo/tests/xo/saved/xo_02.XP.out | 74 + tools/libxo/tests/xo/xo_01.sh | 36 + tools/libxo/tests/xo/xo_02.sh | 57 + tools/libxo/warnings.mk | 57 + tools/libxo/xo/Makefile.am | 43 + tools/libxo/xo/xo.1 | 211 + tools/libxo/xo/xo.c | 555 + tools/libxo/{libxo => }/xo_config.h | 8 +- tools/libxo/xohtml/Makefile.am | 42 + tools/libxo/xohtml/external/jquery.js | 9300 +++++++++++++++++ tools/libxo/xohtml/external/jquery.qtip.css | 599 ++ tools/libxo/xohtml/external/jquery.qtip.js | 2656 +++++ tools/libxo/xohtml/xohtml.1 | 103 + tools/libxo/xohtml/xohtml.css | 1040 ++ tools/libxo/xohtml/xohtml.js | 54 + tools/libxo/xohtml/xohtml.sh.in | 85 + tools/libxo/xolint/Makefile.am | 21 + tools/libxo/xolint/xolint.1 | 89 + tools/libxo/xolint/xolint.pl | 701 ++ tools/libxo/xopo/Makefile.am | 43 + tools/libxo/xopo/xopo.1 | 87 + tools/libxo/xopo/xopo.c | 289 + tools/ndp/Makefile | 16 +- tools/ndp/ndp.c | 118 +- tools/netstat/Makefile | 86 +- tools/netstat/if.c | 18 + tools/netstat/inet.c | 8 + tools/netstat/inet6.c | 21 + tools/netstat/main.c | 118 + tools/netstat/mbuf.c | 10 + tools/netstat/mroute.c | 8 + tools/netstat/netisr.c | 12 + tools/netstat/netstat.h | 6 + tools/netstat/nhops.c | 9 +- tools/netstat/route.c | 17 + tools/netstat/unix.c | 8 + tools/ngctl/Makefile | 10 +- tools/ngctl/main.c | 65 + tools/ngctl/msg.c | 4 + tools/ngctl/ngctl.h | 6 + tools/prog.mk | 4 +- tools/route/Makefile | 18 +- tools/route/route.c | 123 + tools/sysctl/Makefile | 5 +- tools/sysctl/sysctl.c | 173 +- 559 files changed, 60853 insertions(+), 3748 deletions(-) create mode 100644 tools/compat/fnmatch.c create mode 100644 tools/compat/include/net/dlt.h delete mode 100644 tools/compat/include/net/flowtable.h delete mode 100644 tools/compat/include/net/iso88025.h create mode 100644 tools/compat/include/net/route/nhop.h create mode 100644 tools/compat/include/netinet6/ip_fw_nat64.h create mode 100644 tools/compat/include/netinet6/ip_fw_nptv6.h create mode 100644 tools/compat/include/sys/_domainset.h create mode 100644 tools/compat/include/sys/_smr.h create mode 100644 tools/compat/include/sys/ck.h create mode 100644 tools/compat/include/sys/epoch.h create mode 100644 tools/ipfw/compat.c create mode 100644 tools/libnetgraph/compat.c create mode 100644 tools/libxo/.gitignore create mode 100644 tools/libxo/.svnignore create mode 100644 tools/libxo/.travis.yml create mode 100644 tools/libxo/Copyright create mode 100644 tools/libxo/INSTALL.md create mode 100644 tools/libxo/LICENSE create mode 100644 tools/libxo/Makefile.am delete mode 100644 tools/libxo/Makefile.depend create mode 100644 tools/libxo/README.md create mode 100644 tools/libxo/configure.ac create mode 100644 tools/libxo/doc/Makefile.am create mode 100644 tools/libxo/doc/_static/basic.css_t create mode 100644 tools/libxo/doc/_templates/localtoc.html create mode 100644 tools/libxo/doc/api.rst create mode 100644 tools/libxo/doc/conf.py create mode 100644 tools/libxo/doc/encoders.rst create mode 100644 tools/libxo/doc/example.rst create mode 100644 tools/libxo/doc/faq.rst create mode 100644 tools/libxo/doc/field-formatting.rst create mode 100644 tools/libxo/doc/field-modifiers.rst create mode 100644 tools/libxo/doc/field-roles.rst create mode 100644 tools/libxo/doc/format-strings.rst create mode 100644 tools/libxo/doc/formatting.rst create mode 100644 tools/libxo/doc/getting.rst create mode 100644 tools/libxo/doc/howto.rst create mode 100644 tools/libxo/doc/index.rst create mode 100644 tools/libxo/doc/intro.rst create mode 100644 tools/libxo/doc/options.rst create mode 100644 tools/libxo/doc/top-link.html.in create mode 100644 tools/libxo/doc/xo.rst create mode 100644 tools/libxo/doc/xohtml.rst create mode 100644 tools/libxo/doc/xolint.rst create mode 100644 tools/libxo/doc/xopo.rst delete mode 100644 tools/libxo/encoder/Makefile create mode 100644 tools/libxo/encoder/Makefile.am create mode 100644 tools/libxo/encoder/cbor/Makefile.am create mode 100644 tools/libxo/encoder/cbor/enc_cbor.c delete mode 100644 tools/libxo/encoder/csv/Makefile create mode 100644 tools/libxo/encoder/csv/Makefile.am create mode 100644 tools/libxo/encoder/csv/enc_csv.c create mode 100644 tools/libxo/encoder/test/Makefile.am create mode 100644 tools/libxo/encoder/test/enc_test.c create mode 100644 tools/libxo/libxo-config.in delete mode 100644 tools/libxo/libxo/Makefile create mode 100644 tools/libxo/libxo/Makefile.am rename tools/libxo/{add.man => libxo/add.man.in} (82%) create mode 100644 tools/libxo/libxo/gen-wide.sh create mode 100644 tools/libxo/libxo/libxo.3 create mode 100644 tools/libxo/libxo/libxo.c create mode 100644 tools/libxo/libxo/xo.h create mode 100644 tools/libxo/libxo/xo_attr.3 create mode 100644 tools/libxo/libxo/xo_buf.h create mode 100644 tools/libxo/libxo/xo_create.3 create mode 100644 tools/libxo/libxo/xo_emit.3 create mode 100644 tools/libxo/libxo/xo_emit_err.3 create mode 100644 tools/libxo/libxo/xo_emit_f.3 create mode 100644 tools/libxo/libxo/xo_encoder.c create mode 100644 tools/libxo/libxo/xo_encoder.h create mode 100644 tools/libxo/libxo/xo_err.3 create mode 100644 tools/libxo/libxo/xo_error.3 create mode 100644 tools/libxo/libxo/xo_explicit.h create mode 100644 tools/libxo/libxo/xo_finish.3 create mode 100644 tools/libxo/libxo/xo_flush.3 create mode 100644 tools/libxo/libxo/xo_format.5 create mode 100644 tools/libxo/libxo/xo_humanize.h create mode 100644 tools/libxo/libxo/xo_message.3 create mode 100644 tools/libxo/libxo/xo_no_setlocale.3 create mode 100644 tools/libxo/libxo/xo_open_container.3 create mode 100644 tools/libxo/libxo/xo_open_list.3 create mode 100644 tools/libxo/libxo/xo_open_marker.3 create mode 100644 tools/libxo/libxo/xo_options.7 create mode 100644 tools/libxo/libxo/xo_parse_args.3 create mode 100644 tools/libxo/libxo/xo_set_allocator.3 create mode 100644 tools/libxo/libxo/xo_set_flags.3 create mode 100644 tools/libxo/libxo/xo_set_info.3 create mode 100644 tools/libxo/libxo/xo_set_options.3 create mode 100644 tools/libxo/libxo/xo_set_style.3 create mode 100644 tools/libxo/libxo/xo_set_syslog_enterprise_id.3 create mode 100644 tools/libxo/libxo/xo_set_version.3 create mode 100644 tools/libxo/libxo/xo_set_writer.3 create mode 100644 tools/libxo/libxo/xo_syslog.3 create mode 100644 tools/libxo/libxo/xo_syslog.c create mode 100644 tools/libxo/libxo/xo_wcwidth.h create mode 100644 tools/libxo/packaging/libxo.pc.in create mode 100644 tools/libxo/packaging/libxo.rb.base.in create mode 100644 tools/libxo/packaging/libxo.spec.in delete mode 100644 tools/libxo/tests/Makefile create mode 100644 tools/libxo/tests/Makefile.am delete mode 100644 tools/libxo/tests/Makefile.depend create mode 100644 tools/libxo/tests/core/Makefile.am create mode 100644 tools/libxo/tests/core/saved/test_01.E.err create mode 100644 tools/libxo/tests/core/saved/test_01.E.out create mode 100644 tools/libxo/tests/core/saved/test_01.Ecsv1.err create mode 100644 tools/libxo/tests/core/saved/test_01.Ecsv1.out create mode 100644 tools/libxo/tests/core/saved/test_01.Ecsv2.err create mode 100644 tools/libxo/tests/core/saved/test_01.Ecsv2.out create mode 100644 tools/libxo/tests/core/saved/test_01.Ecsv3.err create mode 100644 tools/libxo/tests/core/saved/test_01.Ecsv3.out create mode 100644 tools/libxo/tests/core/saved/test_01.H.err create mode 100644 tools/libxo/tests/core/saved/test_01.H.out create mode 100644 tools/libxo/tests/core/saved/test_01.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_01.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_01.HP.err create mode 100644 tools/libxo/tests/core/saved/test_01.HP.out create mode 100644 tools/libxo/tests/core/saved/test_01.J.err create mode 100644 tools/libxo/tests/core/saved/test_01.J.out create mode 100644 tools/libxo/tests/core/saved/test_01.JP.err create mode 100644 tools/libxo/tests/core/saved/test_01.JP.out create mode 100644 tools/libxo/tests/core/saved/test_01.T.err create mode 100644 tools/libxo/tests/core/saved/test_01.T.out create mode 100644 tools/libxo/tests/core/saved/test_01.X.err create mode 100644 tools/libxo/tests/core/saved/test_01.X.out create mode 100644 tools/libxo/tests/core/saved/test_01.XP.err create mode 100644 tools/libxo/tests/core/saved/test_01.XP.out create mode 100644 tools/libxo/tests/core/saved/test_01.err create mode 100644 tools/libxo/tests/core/saved/test_01.out create mode 100644 tools/libxo/tests/core/saved/test_02.E.err create mode 100644 tools/libxo/tests/core/saved/test_02.E.out create mode 100644 tools/libxo/tests/core/saved/test_02.H.err create mode 100644 tools/libxo/tests/core/saved/test_02.H.out create mode 100644 tools/libxo/tests/core/saved/test_02.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_02.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_02.HP.err create mode 100644 tools/libxo/tests/core/saved/test_02.HP.out create mode 100644 tools/libxo/tests/core/saved/test_02.J.err create mode 100644 tools/libxo/tests/core/saved/test_02.J.out create mode 100644 tools/libxo/tests/core/saved/test_02.JP.err create mode 100644 tools/libxo/tests/core/saved/test_02.JP.out create mode 100644 tools/libxo/tests/core/saved/test_02.T.err create mode 100644 tools/libxo/tests/core/saved/test_02.T.out create mode 100644 tools/libxo/tests/core/saved/test_02.X.err create mode 100644 tools/libxo/tests/core/saved/test_02.X.out create mode 100644 tools/libxo/tests/core/saved/test_02.XP.err create mode 100644 tools/libxo/tests/core/saved/test_02.XP.out create mode 100644 tools/libxo/tests/core/saved/test_02.err create mode 100644 tools/libxo/tests/core/saved/test_02.out create mode 100644 tools/libxo/tests/core/saved/test_03.E.err create mode 100644 tools/libxo/tests/core/saved/test_03.E.out create mode 100644 tools/libxo/tests/core/saved/test_03.H.err create mode 100644 tools/libxo/tests/core/saved/test_03.H.out create mode 100644 tools/libxo/tests/core/saved/test_03.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_03.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_03.HP.err create mode 100644 tools/libxo/tests/core/saved/test_03.HP.out create mode 100644 tools/libxo/tests/core/saved/test_03.J.err create mode 100644 tools/libxo/tests/core/saved/test_03.J.out create mode 100644 tools/libxo/tests/core/saved/test_03.JP.err create mode 100644 tools/libxo/tests/core/saved/test_03.JP.out create mode 100644 tools/libxo/tests/core/saved/test_03.T.err create mode 100644 tools/libxo/tests/core/saved/test_03.T.out create mode 100644 tools/libxo/tests/core/saved/test_03.X.err create mode 100644 tools/libxo/tests/core/saved/test_03.X.out create mode 100644 tools/libxo/tests/core/saved/test_03.XP.err create mode 100644 tools/libxo/tests/core/saved/test_03.XP.out create mode 100644 tools/libxo/tests/core/saved/test_03.err create mode 100644 tools/libxo/tests/core/saved/test_03.out create mode 100644 tools/libxo/tests/core/saved/test_04.E.err create mode 100644 tools/libxo/tests/core/saved/test_04.E.out create mode 100644 tools/libxo/tests/core/saved/test_04.H.err create mode 100644 tools/libxo/tests/core/saved/test_04.H.out create mode 100644 tools/libxo/tests/core/saved/test_04.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_04.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_04.HP.err create mode 100644 tools/libxo/tests/core/saved/test_04.HP.out create mode 100644 tools/libxo/tests/core/saved/test_04.J.err create mode 100644 tools/libxo/tests/core/saved/test_04.J.out create mode 100644 tools/libxo/tests/core/saved/test_04.JP.err create mode 100644 tools/libxo/tests/core/saved/test_04.JP.out create mode 100644 tools/libxo/tests/core/saved/test_04.T.err create mode 100644 tools/libxo/tests/core/saved/test_04.T.out create mode 100644 tools/libxo/tests/core/saved/test_04.X.err create mode 100644 tools/libxo/tests/core/saved/test_04.X.out create mode 100644 tools/libxo/tests/core/saved/test_04.XP.err create mode 100644 tools/libxo/tests/core/saved/test_04.XP.out create mode 100644 tools/libxo/tests/core/saved/test_05.E.err create mode 100644 tools/libxo/tests/core/saved/test_05.E.out create mode 100644 tools/libxo/tests/core/saved/test_05.H.err create mode 100644 tools/libxo/tests/core/saved/test_05.H.out create mode 100644 tools/libxo/tests/core/saved/test_05.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_05.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_05.HP.err create mode 100644 tools/libxo/tests/core/saved/test_05.HP.out create mode 100644 tools/libxo/tests/core/saved/test_05.J.err create mode 100644 tools/libxo/tests/core/saved/test_05.J.out create mode 100644 tools/libxo/tests/core/saved/test_05.JP.err create mode 100644 tools/libxo/tests/core/saved/test_05.JP.out create mode 100644 tools/libxo/tests/core/saved/test_05.T.err create mode 100644 tools/libxo/tests/core/saved/test_05.T.out create mode 100644 tools/libxo/tests/core/saved/test_05.X.err create mode 100644 tools/libxo/tests/core/saved/test_05.X.out create mode 100644 tools/libxo/tests/core/saved/test_05.XP.err create mode 100644 tools/libxo/tests/core/saved/test_05.XP.out create mode 100644 tools/libxo/tests/core/saved/test_06.E.err create mode 100644 tools/libxo/tests/core/saved/test_06.E.out create mode 100644 tools/libxo/tests/core/saved/test_06.H.err create mode 100644 tools/libxo/tests/core/saved/test_06.H.out create mode 100644 tools/libxo/tests/core/saved/test_06.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_06.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_06.HP.err create mode 100644 tools/libxo/tests/core/saved/test_06.HP.out create mode 100644 tools/libxo/tests/core/saved/test_06.J.err create mode 100644 tools/libxo/tests/core/saved/test_06.J.out create mode 100644 tools/libxo/tests/core/saved/test_06.JP.err create mode 100644 tools/libxo/tests/core/saved/test_06.JP.out create mode 100644 tools/libxo/tests/core/saved/test_06.T.err create mode 100644 tools/libxo/tests/core/saved/test_06.T.out create mode 100644 tools/libxo/tests/core/saved/test_06.X.err create mode 100644 tools/libxo/tests/core/saved/test_06.X.out create mode 100644 tools/libxo/tests/core/saved/test_06.XP.err create mode 100644 tools/libxo/tests/core/saved/test_06.XP.out create mode 100644 tools/libxo/tests/core/saved/test_07.E.err create mode 100644 tools/libxo/tests/core/saved/test_07.E.out create mode 100644 tools/libxo/tests/core/saved/test_07.H.err create mode 100644 tools/libxo/tests/core/saved/test_07.H.out create mode 100644 tools/libxo/tests/core/saved/test_07.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_07.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_07.HP.err create mode 100644 tools/libxo/tests/core/saved/test_07.HP.out create mode 100644 tools/libxo/tests/core/saved/test_07.J.err create mode 100644 tools/libxo/tests/core/saved/test_07.J.out create mode 100644 tools/libxo/tests/core/saved/test_07.JP.err create mode 100644 tools/libxo/tests/core/saved/test_07.JP.out create mode 100644 tools/libxo/tests/core/saved/test_07.T.err create mode 100644 tools/libxo/tests/core/saved/test_07.T.out create mode 100644 tools/libxo/tests/core/saved/test_07.X.err create mode 100644 tools/libxo/tests/core/saved/test_07.X.out create mode 100644 tools/libxo/tests/core/saved/test_07.XP.err create mode 100644 tools/libxo/tests/core/saved/test_07.XP.out create mode 100644 tools/libxo/tests/core/saved/test_08.E.err create mode 100644 tools/libxo/tests/core/saved/test_08.E.out create mode 100644 tools/libxo/tests/core/saved/test_08.H.err create mode 100644 tools/libxo/tests/core/saved/test_08.H.out create mode 100644 tools/libxo/tests/core/saved/test_08.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_08.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_08.HP.err create mode 100644 tools/libxo/tests/core/saved/test_08.HP.out create mode 100644 tools/libxo/tests/core/saved/test_08.J.err create mode 100644 tools/libxo/tests/core/saved/test_08.J.out create mode 100644 tools/libxo/tests/core/saved/test_08.JP.err create mode 100644 tools/libxo/tests/core/saved/test_08.JP.out create mode 100644 tools/libxo/tests/core/saved/test_08.T.err create mode 100644 tools/libxo/tests/core/saved/test_08.T.out create mode 100644 tools/libxo/tests/core/saved/test_08.X.err create mode 100644 tools/libxo/tests/core/saved/test_08.X.out create mode 100644 tools/libxo/tests/core/saved/test_08.XP.err create mode 100644 tools/libxo/tests/core/saved/test_08.XP.out create mode 100644 tools/libxo/tests/core/saved/test_09.E.err create mode 100644 tools/libxo/tests/core/saved/test_09.E.out create mode 100644 tools/libxo/tests/core/saved/test_09.H.err create mode 100644 tools/libxo/tests/core/saved/test_09.H.out create mode 100644 tools/libxo/tests/core/saved/test_09.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_09.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_09.HP.err create mode 100644 tools/libxo/tests/core/saved/test_09.HP.out create mode 100644 tools/libxo/tests/core/saved/test_09.J.err create mode 100644 tools/libxo/tests/core/saved/test_09.J.out create mode 100644 tools/libxo/tests/core/saved/test_09.JP.err create mode 100644 tools/libxo/tests/core/saved/test_09.JP.out create mode 100644 tools/libxo/tests/core/saved/test_09.T.err create mode 100644 tools/libxo/tests/core/saved/test_09.T.out create mode 100644 tools/libxo/tests/core/saved/test_09.X.err create mode 100644 tools/libxo/tests/core/saved/test_09.X.out create mode 100644 tools/libxo/tests/core/saved/test_09.XP.err create mode 100644 tools/libxo/tests/core/saved/test_09.XP.out create mode 100644 tools/libxo/tests/core/saved/test_10.E.err create mode 100644 tools/libxo/tests/core/saved/test_10.E.out create mode 100644 tools/libxo/tests/core/saved/test_10.H.err create mode 100644 tools/libxo/tests/core/saved/test_10.H.out create mode 100644 tools/libxo/tests/core/saved/test_10.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_10.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_10.HP.err create mode 100644 tools/libxo/tests/core/saved/test_10.HP.out create mode 100644 tools/libxo/tests/core/saved/test_10.J.err create mode 100644 tools/libxo/tests/core/saved/test_10.J.out create mode 100644 tools/libxo/tests/core/saved/test_10.JP.err create mode 100644 tools/libxo/tests/core/saved/test_10.JP.out create mode 100644 tools/libxo/tests/core/saved/test_10.T.err create mode 100644 tools/libxo/tests/core/saved/test_10.T.out create mode 100644 tools/libxo/tests/core/saved/test_10.X.err create mode 100644 tools/libxo/tests/core/saved/test_10.X.out create mode 100644 tools/libxo/tests/core/saved/test_10.XP.err create mode 100644 tools/libxo/tests/core/saved/test_10.XP.out create mode 100644 tools/libxo/tests/core/saved/test_10.err create mode 100644 tools/libxo/tests/core/saved/test_10.out create mode 100644 tools/libxo/tests/core/saved/test_11.E.err create mode 100644 tools/libxo/tests/core/saved/test_11.E.out create mode 100644 tools/libxo/tests/core/saved/test_11.H.err create mode 100644 tools/libxo/tests/core/saved/test_11.H.out create mode 100644 tools/libxo/tests/core/saved/test_11.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_11.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_11.HP.err create mode 100644 tools/libxo/tests/core/saved/test_11.HP.out create mode 100644 tools/libxo/tests/core/saved/test_11.J.err create mode 100644 tools/libxo/tests/core/saved/test_11.J.out create mode 100644 tools/libxo/tests/core/saved/test_11.JP.err create mode 100644 tools/libxo/tests/core/saved/test_11.JP.out create mode 100644 tools/libxo/tests/core/saved/test_11.T.err create mode 100644 tools/libxo/tests/core/saved/test_11.T.out create mode 100644 tools/libxo/tests/core/saved/test_11.X.err create mode 100644 tools/libxo/tests/core/saved/test_11.X.out create mode 100644 tools/libxo/tests/core/saved/test_11.XP.err create mode 100644 tools/libxo/tests/core/saved/test_11.XP.out create mode 100644 tools/libxo/tests/core/saved/test_12.E.err create mode 100644 tools/libxo/tests/core/saved/test_12.E.out create mode 100644 tools/libxo/tests/core/saved/test_12.H.err create mode 100644 tools/libxo/tests/core/saved/test_12.H.out create mode 100644 tools/libxo/tests/core/saved/test_12.HIPx.err create mode 100644 tools/libxo/tests/core/saved/test_12.HIPx.out create mode 100644 tools/libxo/tests/core/saved/test_12.HP.err create mode 100644 tools/libxo/tests/core/saved/test_12.HP.out create mode 100644 tools/libxo/tests/core/saved/test_12.J.err create mode 100644 tools/libxo/tests/core/saved/test_12.J.out create mode 100644 tools/libxo/tests/core/saved/test_12.JP.err create mode 100644 tools/libxo/tests/core/saved/test_12.JP.out create mode 100644 tools/libxo/tests/core/saved/test_12.T.err create mode 100644 tools/libxo/tests/core/saved/test_12.T.out create mode 100644 tools/libxo/tests/core/saved/test_12.X.err create mode 100644 tools/libxo/tests/core/saved/test_12.X.out create mode 100644 tools/libxo/tests/core/saved/test_12.XP.err create mode 100644 tools/libxo/tests/core/saved/test_12.XP.out create mode 100644 tools/libxo/tests/core/test_01.c create mode 100644 tools/libxo/tests/core/test_02.c create mode 100644 tools/libxo/tests/core/test_03.c create mode 100644 tools/libxo/tests/core/test_04.c create mode 100644 tools/libxo/tests/core/test_05.c create mode 100644 tools/libxo/tests/core/test_06.c create mode 100644 tools/libxo/tests/core/test_07.c create mode 100644 tools/libxo/tests/core/test_08.c create mode 100644 tools/libxo/tests/core/test_09.c create mode 100644 tools/libxo/tests/core/test_10.c create mode 100644 tools/libxo/tests/core/test_11.c create mode 100644 tools/libxo/tests/core/test_12.c delete mode 100644 tools/libxo/tests/encoder/Makefile delete mode 100644 tools/libxo/tests/encoder/Makefile.depend delete mode 100644 tools/libxo/tests/functional_test.sh create mode 100644 tools/libxo/tests/gettext/Makefile.am create mode 100644 tools/libxo/tests/gettext/gt_01.c create mode 100644 tools/libxo/tests/gettext/gt_01.pot create mode 100644 tools/libxo/tests/gettext/ldns.pot create mode 100644 tools/libxo/tests/gettext/po/pig_latin/gt_01.po create mode 100644 tools/libxo/tests/gettext/po/pig_latin/ldns.po create mode 100644 tools/libxo/tests/gettext/po/pig_latin/strerror.po create mode 100644 tools/libxo/tests/gettext/saved/gt_01.H.err create mode 100644 tools/libxo/tests/gettext/saved/gt_01.H.out create mode 100644 tools/libxo/tests/gettext/saved/gt_01.HIPx.err create mode 100644 tools/libxo/tests/gettext/saved/gt_01.HIPx.out create mode 100644 tools/libxo/tests/gettext/saved/gt_01.HP.err create mode 100644 tools/libxo/tests/gettext/saved/gt_01.HP.out create mode 100644 tools/libxo/tests/gettext/saved/gt_01.J.err create mode 100644 tools/libxo/tests/gettext/saved/gt_01.J.out create mode 100644 tools/libxo/tests/gettext/saved/gt_01.JP.err create mode 100644 tools/libxo/tests/gettext/saved/gt_01.JP.out create mode 100644 tools/libxo/tests/gettext/saved/gt_01.T.err create mode 100644 tools/libxo/tests/gettext/saved/gt_01.T.out create mode 100644 tools/libxo/tests/gettext/saved/gt_01.X.err create mode 100644 tools/libxo/tests/gettext/saved/gt_01.X.out create mode 100644 tools/libxo/tests/gettext/saved/gt_01.XP.err create mode 100644 tools/libxo/tests/gettext/saved/gt_01.XP.out create mode 100644 tools/libxo/tests/gettext/strerror.pot create mode 100644 tools/libxo/tests/xo/Makefile.am create mode 100644 tools/libxo/tests/xo/saved/xo_01.H.err create mode 100644 tools/libxo/tests/xo/saved/xo_01.H.out create mode 100644 tools/libxo/tests/xo/saved/xo_01.HIPx.err create mode 100644 tools/libxo/tests/xo/saved/xo_01.HIPx.out create mode 100644 tools/libxo/tests/xo/saved/xo_01.HP.err create mode 100644 tools/libxo/tests/xo/saved/xo_01.HP.out create mode 100644 tools/libxo/tests/xo/saved/xo_01.J.err create mode 100644 tools/libxo/tests/xo/saved/xo_01.J.out create mode 100644 tools/libxo/tests/xo/saved/xo_01.JP.err create mode 100644 tools/libxo/tests/xo/saved/xo_01.JP.out create mode 100644 tools/libxo/tests/xo/saved/xo_01.T.err create mode 100644 tools/libxo/tests/xo/saved/xo_01.T.out create mode 100644 tools/libxo/tests/xo/saved/xo_01.X.err create mode 100644 tools/libxo/tests/xo/saved/xo_01.X.out create mode 100644 tools/libxo/tests/xo/saved/xo_01.XP.err create mode 100644 tools/libxo/tests/xo/saved/xo_01.XP.out create mode 100644 tools/libxo/tests/xo/saved/xo_02.H.err create mode 100644 tools/libxo/tests/xo/saved/xo_02.H.out create mode 100644 tools/libxo/tests/xo/saved/xo_02.HIPx.err create mode 100644 tools/libxo/tests/xo/saved/xo_02.HIPx.out create mode 100644 tools/libxo/tests/xo/saved/xo_02.HP.err create mode 100644 tools/libxo/tests/xo/saved/xo_02.HP.out create mode 100644 tools/libxo/tests/xo/saved/xo_02.J.err create mode 100644 tools/libxo/tests/xo/saved/xo_02.J.out create mode 100644 tools/libxo/tests/xo/saved/xo_02.JP.err create mode 100644 tools/libxo/tests/xo/saved/xo_02.JP.out create mode 100644 tools/libxo/tests/xo/saved/xo_02.T.err create mode 100644 tools/libxo/tests/xo/saved/xo_02.T.out create mode 100644 tools/libxo/tests/xo/saved/xo_02.X.err create mode 100644 tools/libxo/tests/xo/saved/xo_02.X.out create mode 100644 tools/libxo/tests/xo/saved/xo_02.XP.err create mode 100644 tools/libxo/tests/xo/saved/xo_02.XP.out create mode 100644 tools/libxo/tests/xo/xo_01.sh create mode 100644 tools/libxo/tests/xo/xo_02.sh create mode 100644 tools/libxo/warnings.mk create mode 100644 tools/libxo/xo/Makefile.am create mode 100644 tools/libxo/xo/xo.1 create mode 100644 tools/libxo/xo/xo.c rename tools/libxo/{libxo => }/xo_config.h (97%) create mode 100644 tools/libxo/xohtml/Makefile.am create mode 100644 tools/libxo/xohtml/external/jquery.js create mode 100644 tools/libxo/xohtml/external/jquery.qtip.css create mode 100644 tools/libxo/xohtml/external/jquery.qtip.js create mode 100644 tools/libxo/xohtml/xohtml.1 create mode 100644 tools/libxo/xohtml/xohtml.css create mode 100644 tools/libxo/xohtml/xohtml.js create mode 100644 tools/libxo/xohtml/xohtml.sh.in create mode 100644 tools/libxo/xolint/Makefile.am create mode 100644 tools/libxo/xolint/xolint.1 create mode 100644 tools/libxo/xolint/xolint.pl create mode 100644 tools/libxo/xopo/Makefile.am create mode 100644 tools/libxo/xopo/xopo.1 create mode 100644 tools/libxo/xopo/xopo.c diff --git a/tools/README.md b/tools/README.md index 2e722104c..c938e4381 100644 --- a/tools/README.md +++ b/tools/README.md @@ -145,18 +145,18 @@ Examples: # netstat Usage: ``` - netstat -P [-46AaLnRSTWx] [-f protocol_family | -p protocol] - netstat -P -i | -I interface [-46abdhnW] [-f address_family] - netstat -P -w wait [-I interface] [-46d] [-q howmany] - netstat -P -s [-46sz] [-f protocol_family | -p protocol] - netstat -P -i | -I interface -s [-46s] + netstat -t [-46AaLnRSTWx] [-f protocol_family | -p protocol] + netstat -t -i | -I interface [-46abdhnW] [-f address_family] + netstat -t -w wait [-I interface] [-46d] [-q howmany] + netstat -t -s [-46sz] [-f protocol_family | -p protocol] + netstat -t -i | -I interface -s [-46s] [-f protocol_family | -p protocol] - netstat -P -B [-z] [-I interface] - netstat -P -r [-46AnW] [-F fibnum] [-f address_family] - netstat -P -rs [-s] - netstat -P -g [-46W] [-f address_family] - netstat -P -gs [-46s] [-f address_family] - netstat -P -Q + netstat -t -B [-z] [-I interface] + netstat -t -r [-46AnW] [-F fibnum] [-f address_family] + netstat -t -rs [-s] + netstat -t -g [-46W] [-f address_family] + netstat -t -gs [-46s] [-f address_family] + netstat -t -Q ``` Unsupported commands or features: diff --git a/tools/arp/Makefile b/tools/arp/Makefile index b6ff7a3e2..a7eef06d0 100644 --- a/tools/arp/Makefile +++ b/tools/arp/Makefile @@ -1,11 +1,11 @@ # @(#)Makefile 8.2 (Berkeley) 4/18/94 # $FreeBSD$ -PROG= arp -MAN= arp.4 arp.8 +TOPDIR?=${CURDIR}/../.. -LIBADD= xo +PROG=arp -WARNS?= 3 +LIBADD += xo util + +include ${TOPDIR}/tools/prog.mk -.include diff --git a/tools/arp/arp.c b/tools/arp/arp.c index 08698c7bc..e42ce850d 100644 --- a/tools/arp/arp.c +++ b/tools/arp/arp.c @@ -81,6 +81,21 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef FSTACK +#include +#include "rtioctl.h" +#include "ff_ipc.h" + +#ifndef __unused +#define __unused __attribute__((__unused__)) + +#define socket(a, b, c) rt_socket((a), (b), (c)) +#define close(a) rt_close(a) + +#endif + +#endif + typedef void (action_fn)(struct sockaddr_dl *sdl, struct sockaddr_in *s_in, struct rt_msghdr *rtm); @@ -129,7 +144,12 @@ main(int argc, char *argv[]) if (argc < 0) exit(1); +#ifndef FSTACK while ((ch = getopt(argc, argv, "andfsSi:")) != -1) +#else + ff_ipc_init(); + while ((ch = getopt(argc, argv, "andfsSi:p:")) != -1) +#endif switch(ch) { case 'a': aflag = 1; @@ -152,6 +172,11 @@ main(int argc, char *argv[]) case 'i': rifname = optarg; break; +#ifdef FSTACK + case 'p': + ff_set_proc_id(atoi(optarg)); + break; +#endif case '?': default: usage(); @@ -222,6 +247,10 @@ main(int argc, char *argv[]) if (ifnameindex != NULL) if_freenameindex(ifnameindex); +#ifdef FSTACK + ff_ipc_exit(); +#endif + return (rtn); } @@ -271,7 +300,9 @@ file(char *name) static struct sockaddr_in * getaddr(char *host) { +#ifndef FSTACK struct hostent *hp; +#endif static struct sockaddr_in reply; bzero(&reply, sizeof(reply)); @@ -279,12 +310,16 @@ getaddr(char *host) reply.sin_family = AF_INET; reply.sin_addr.s_addr = inet_addr(host); if (reply.sin_addr.s_addr == INADDR_NONE) { +#ifndef FSTACK if (!(hp = gethostbyname(host))) { xo_warnx("%s: %s", host, hstrerror(h_errno)); return (NULL); } bcopy((char *)hp->h_addr, (char *)&reply.sin_addr, sizeof reply.sin_addr); +#else + warnx("reply.sin_addr.s_addr == INADDR_NONE"); +#endif } return (&reply); } @@ -701,6 +736,7 @@ static void usage(void) { fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n", +#ifndef FSTACK "usage: arp [-n] [-i interface] hostname", " arp [-n] [-i interface] -a", " arp -d hostname [pub]", @@ -708,6 +744,19 @@ usage(void) " arp -s hostname ether_addr [temp] [reject | blackhole] [pub [only]]", " arp -S hostname ether_addr [temp] [reject | blackhole] [pub [only]]", " arp -f filename"); +#else + "usage: arp -p [-n] [-i interface] hostname", + " arp -p [-n] [-i interface] -a", + " arp -p -d hostname [pub]", + " arp -p -d [-i interface] -a", + " arp -p -s hostname ether_addr [temp] [reject | blackhole] [pub [only]]", + " arp -p -S hostname ether_addr [temp] [reject | blackhole] [pub [only]]", + " arp -p -f filename"); +#endif +#ifdef FSTACK + ff_ipc_exit(); +#endif + exit(1); } @@ -774,6 +823,7 @@ doit: l = rtm->rtm_msglen; rtm->rtm_seq = ++seq; rtm->rtm_type = cmd; +#ifndef FSTACK if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) { if (errno != ESRCH || cmd != RTM_DELETE) { xo_warn("writing to routing socket"); @@ -784,6 +834,9 @@ doit: l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm->rtm_type != cmd || rtm->rtm_seq != seq || rtm->rtm_pid != pid)); +#else + l = rtioctl((char *)&m_rtmsg, l, sizeof(m_rtmsg)); +#endif if (l < 0) xo_warn("read from routing socket"); return (rtm); diff --git a/tools/compat/compat.h b/tools/compat/compat.h index 508f29f21..fe28ad2b3 100644 --- a/tools/compat/compat.h +++ b/tools/compat/compat.h @@ -105,4 +105,6 @@ const char *getprogname(void); extern int optreset; +int fnmatch(const char *, const char *, int); + #endif diff --git a/tools/compat/fnmatch.c b/tools/compat/fnmatch.c new file mode 100644 index 000000000..d69ba3e41 --- /dev/null +++ b/tools/compat/fnmatch.c @@ -0,0 +1,238 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1989, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#ifndef FSTACK +__FBSDID("$FreeBSD$"); +#endif + +/* + * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. + * Compares a filename or pathname to a pattern. + */ + +#include +#ifndef FSTACK +#include +#include +#else +#include +#include +#include + +/* fnmatch() return values. */ +#define FNM_NOMATCH 1 /* Match failed. */ + +/* fnmatch() flags. */ +#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ +#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ +#define FNM_PERIOD 0x04 /* Period must be matched by period. */ +#define FNM_LEADING_DIR 0x08 /* Ignore / after Imatch. */ +#define FNM_CASEFOLD 0x10 /* Case insensitive search. */ +#define FNM_IGNORECASE FNM_CASEFOLD +#define FNM_FILE_NAME FNM_PATHNAME + +#endif + +#define EOS '\0' + +#define RANGE_MATCH 1 +#define RANGE_NOMATCH 0 +#define RANGE_ERROR (-1) + + +static int rangematch(const char *, char, int, char **); + +int +fnmatch(const char *pattern, const char *string, int flags) +{ + const char *stringstart; + char *newp; + char c, test; + + for (stringstart = string;;) + switch (c = *pattern++) { + case EOS: + if ((flags & FNM_LEADING_DIR) && *string == '/') + return (0); + return (*string == EOS ? 0 : FNM_NOMATCH); + case '?': + if (*string == EOS) + return (FNM_NOMATCH); + if (*string == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + ++string; + break; + case '*': + c = *pattern; + /* Collapse multiple stars. */ + while (c == '*') + c = *++pattern; + + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + + /* Optimize for pattern with * at end or before /. */ + if (c == EOS) + if (flags & FNM_PATHNAME) + return ((flags & FNM_LEADING_DIR) || + strchr(string, '/') == NULL ? + 0 : FNM_NOMATCH); + else + return (0); + else if (c == '/' && flags & FNM_PATHNAME) { + if ((string = strchr(string, '/')) == NULL) + return (FNM_NOMATCH); + break; + } + + /* General case, use recursion. */ + while ((test = *string) != EOS) { + if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) + return (0); + if (test == '/' && flags & FNM_PATHNAME) + break; + ++string; + } + return (FNM_NOMATCH); + case '[': + if (*string == EOS) + return (FNM_NOMATCH); + if (*string == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + + switch (rangematch(pattern, *string, flags, &newp)) { + case RANGE_ERROR: + goto norm; + case RANGE_MATCH: + pattern = newp; + break; + case RANGE_NOMATCH: + return (FNM_NOMATCH); + } + ++string; + break; + case '\\': + if (!(flags & FNM_NOESCAPE)) { + if ((c = *pattern++) == EOS) { + c = '\\'; + --pattern; + } + } + /* FALLTHROUGH */ + default: + norm: + if (c == *string) + ; + else if ((flags & FNM_CASEFOLD) && + (tolower((unsigned char)c) == + tolower((unsigned char)*string))) + ; + else + return (FNM_NOMATCH); + string++; + break; + } + /* NOTREACHED */ +} + +static int +rangematch(const char *pattern, char test, int flags, char **newp) +{ + int negate, ok; + char c, c2; + + /* + * A bracket expression starting with an unquoted circumflex + * character produces unspecified results (IEEE 1003.2-1992, + * 3.13.2). This implementation treats it like '!', for + * consistency with the regular expression syntax. + * J.T. Conklin (conklin@ngai.kaleida.com) + */ + if ( (negate = (*pattern == '!' || *pattern == '^')) ) + ++pattern; + + if (flags & FNM_CASEFOLD) + test = tolower((unsigned char)test); + + /* + * A right bracket shall lose its special meaning and represent + * itself in a bracket expression if it occurs first in the list. + * -- POSIX.2 2.8.3.2 + */ + ok = 0; + c = *pattern++; + do { + if (c == '\\' && !(flags & FNM_NOESCAPE)) + c = *pattern++; + if (c == EOS) + return (RANGE_ERROR); + + if (c == '/' && (flags & FNM_PATHNAME)) + return (RANGE_NOMATCH); + + if (flags & FNM_CASEFOLD) + c = tolower((unsigned char)c); + + if (*pattern == '-' + && (c2 = *(pattern+1)) != EOS && c2 != ']') { + pattern += 2; + if (c2 == '\\' && !(flags & FNM_NOESCAPE)) + c2 = *pattern++; + if (c2 == EOS) + return (RANGE_ERROR); + + if (flags & FNM_CASEFOLD) + c2 = tolower((unsigned char)c2); + + if (c <= test && test <= c2) + ok = 1; + } else if (c == test) + ok = 1; + } while ((c = *pattern++) != ']'); + + *newp = (char *)(uintptr_t)pattern; + return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); +} diff --git a/tools/compat/getaddrinfo.c b/tools/compat/getaddrinfo.c index c03e1fa84..0e022397b 100644 --- a/tools/compat/getaddrinfo.c +++ b/tools/compat/getaddrinfo.c @@ -39,6 +39,7 @@ #include "sys/socket.h" #include "netdb.h" +/* FIXME: to support IPv6 */ /* Just conver numeric hostname to int and not do anything else. */ int getaddrinfo(const char *hostname, const char *servername, diff --git a/tools/compat/include/alias.h b/tools/compat/include/alias.h index b12b353a0..671241212 100644 --- a/tools/compat/include/alias.h +++ b/tools/compat/include/alias.h @@ -1,6 +1,8 @@ /* lint -save -library Flexelint comment for external headers */ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2001 Charles Mott * All rights reserved. * @@ -91,10 +93,10 @@ unsigned int void LibAliasUninit(struct libalias *); /* Packet Handling functions. */ -int LibAliasIn (struct libalias *, char *_ptr, int _maxpacketsize); -int LibAliasOut(struct libalias *, char *_ptr, int _maxpacketsize); -int LibAliasOutTry(struct libalias *, char *_ptr, int _maxpacketsize, int _create); -int LibAliasUnaliasOut(struct libalias *, char *_ptr, int _maxpacketsize); +int LibAliasIn (struct libalias *, void *_ptr, int _maxpacketsize); +int LibAliasOut(struct libalias *, void *_ptr, int _maxpacketsize); +int LibAliasOutTry(struct libalias *, void *_ptr, int _maxpacketsize, int _create); +int LibAliasUnaliasOut(struct libalias *, void *_ptr, int _maxpacketsize); /* Port and address redirection functions. */ @@ -117,9 +119,9 @@ LibAliasRedirectProto(struct libalias *, struct in_addr _src_addr, unsigned char _proto); /* Fragment Handling functions. */ -void LibAliasFragmentIn(struct libalias *, char *_ptr, char *_ptr_fragment); -char *LibAliasGetFragment(struct libalias *, char *_ptr); -int LibAliasSaveFragment(struct libalias *, char *_ptr); +void LibAliasFragmentIn(struct libalias *, void *_ptr, void *_ptr_fragment); +void *LibAliasGetFragment(struct libalias *, void *_ptr); +int LibAliasSaveFragment(struct libalias *, void *_ptr); /* Miscellaneous functions. */ int LibAliasCheckNewLink(struct libalias *); @@ -142,7 +144,6 @@ struct mbuf *m_megapullup(struct mbuf *, int); * Mode flags and other constants. */ - /* Mode flags, set using PacketAliasSetMode() */ /* @@ -226,6 +227,14 @@ struct mbuf *m_megapullup(struct mbuf *, int); */ #define PKT_ALIAS_SKIP_GLOBAL 0x200 +/* + * Like PKT_ALIAS_UNREGISTERED_ONLY, but includes the RFC 6598 + * (Carrier Grade NAT) address range as follows: + * + * 100.64.0.0 -> 100.127.255.255 + */ +#define PKT_ALIAS_UNREGISTERED_CGN 0x400 + /* Function return codes. */ #define PKT_ALIAS_ERROR -1 #define PKT_ALIAS_OK 1 diff --git a/tools/compat/include/net/bpf.h b/tools/compat/include/net/bpf.h index 77ee05254..92db7aa0d 100644 --- a/tools/compat/include/net/bpf.h +++ b/tools/compat/include/net/bpf.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1990, 1991, 1993 * The Regents of the University of California. All rights reserved. * @@ -15,7 +17,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -40,6 +42,9 @@ #ifndef _NET_BPF_H_ #define _NET_BPF_H_ +#include +#include + /* BSD style release date */ #define BPF_RELEASE 199606 @@ -231,1057 +236,6 @@ struct bpf_zbuf_header { u_int _bzh_pad[5]; }; -/* - * Data-link level type codes. - */ -#define DLT_NULL 0 /* BSD loopback encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* IEEE 802 Networks */ -#define DLT_ARCNET 7 /* ARCNET */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ -#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ -#define DLT_RAW 12 /* raw IP */ - -/* - * These are values from BSD/OS's "bpf.h". - * These are not the same as the values from the traditional libpcap - * "bpf.h"; however, these values shouldn't be generated by any - * OS other than BSD/OS, so the correct values to use here are the - * BSD/OS values. - * - * Platforms that have already assigned these values to other - * DLT_ codes, however, should give these codes the values - * from that platform, so that programs that use these codes will - * continue to compile - even though they won't correctly read - * files of these types. - */ -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ - -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ - -/* - * These values are defined by NetBSD; other platforms should refrain from - * using them for other purposes, so that NetBSD savefiles with link - * types of 50 or 51 can be read as this type on all platforms. - */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ - -/* - * Reserved for the Symantec Enterprise Firewall. - */ -#define DLT_SYMANTEC_FIREWALL 99 - -/* - * Values between 100 and 103 are used in capture file headers as - * link-layer header type LINKTYPE_ values corresponding to DLT_ types - * that differ between platforms; don't use those values for new DLT_ - * new types. - */ - -/* - * Values starting with 104 are used for newly-assigned link-layer - * header type values; for those link-layer header types, the DLT_ - * value returned by pcap_datalink() and passed to pcap_open_dead(), - * and the LINKTYPE_ value that appears in capture files, are the - * same. - * - * DLT_MATCHING_MIN is the lowest such value; DLT_MATCHING_MAX is - * the highest such value. - */ -#define DLT_MATCHING_MIN 104 - -/* - * This value was defined by libpcap 0.5; platforms that have defined - * it with a different value should define it here with that value - - * a link type of 104 in a save file will be mapped to DLT_C_HDLC, - * whatever value that happens to be, so programs will correctly - * handle files with that link type regardless of the value of - * DLT_C_HDLC. - * - * The name DLT_C_HDLC was used by BSD/OS; we use that name for source - * compatibility with programs written for BSD/OS. - * - * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, - * for source compatibility with programs written for libpcap 0.5. - */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC - -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ - -/* - * Values between 106 and 107 are used in capture file headers as - * link-layer types corresponding to DLT_ types that might differ - * between platforms; don't use those values for new DLT_ new types. - */ - -/* - * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides - * with other values. - * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header - * (DLCI, etc.). - */ -#define DLT_FRELAY 107 - -/* - * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except - * that the AF_ type in the link-layer header is in network byte order. - * - * OpenBSD defines it as 12, but that collides with DLT_RAW, so we - * define it as 108 here. If OpenBSD picks up this file, it should - * define DLT_LOOP as 12 in its version, as per the comment above - - * and should not use 108 as a DLT_ value. - */ -#define DLT_LOOP 108 - -/* - * Values between 109 and 112 are used in capture file headers as - * link-layer types corresponding to DLT_ types that might differ - * between platforms; don't use those values for new DLT_ new types. - */ - -/* - * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's - * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other - * than OpenBSD. - */ -#define DLT_ENC 109 - -/* - * This is for Linux cooked sockets. - */ -#define DLT_LINUX_SLL 113 - -/* - * Apple LocalTalk hardware. - */ -#define DLT_LTALK 114 - -/* - * Acorn Econet. - */ -#define DLT_ECONET 115 - -/* - * Reserved for use with OpenBSD ipfilter. - */ -#define DLT_IPFILTER 116 - -/* - * Reserved for use in capture-file headers as a link-layer type - * corresponding to OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, - * but that's DLT_LANE8023 in SuSE 6.3, so we can't use 17 for it - * in capture-file headers. - */ -#define DLT_PFLOG 117 - -/* - * Registered for Cisco-internal use. - */ -#define DLT_CISCO_IOS 118 - -/* - * Reserved for 802.11 cards using the Prism II chips, with a link-layer - * header including Prism monitor mode information plus an 802.11 - * header. - */ -#define DLT_PRISM_HEADER 119 - -/* - * Reserved for Aironet 802.11 cards, with an Aironet link-layer header - * (see Doug Ambrisko's FreeBSD patches). - */ -#define DLT_AIRONET_HEADER 120 - -/* - * Reserved for use by OpenBSD's pfsync device. - */ -#define DLT_PFSYNC 121 - -/* - * Reserved for Siemens HiPath HDLC. XXX - */ -#define DLT_HHDLC 121 - -/* - * Reserved for RFC 2625 IP-over-Fibre Channel. - */ -#define DLT_IP_OVER_FC 122 - -/* - * Reserved for Full Frontal ATM on Solaris. - */ -#define DLT_SUNATM 123 - -/* - * Reserved as per request from Kent Dahlgren - * for private use. - */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ - -/* - * BSD header for 802.11 plus a number of bits of link-layer information - * including radio information. - */ -#ifndef DLT_IEEE802_11_RADIO -#define DLT_IEEE802_11_RADIO 127 -#endif - -/* - * Reserved for TZSP encapsulation. - */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ - -/* - * Reserved for Linux ARCNET. - */ -#define DLT_ARCNET_LINUX 129 - -/* - * Juniper-private data link types. - */ -#define DLT_JUNIPER_MLPPP 130 -#define DLT_JUNIPER_MLFR 131 -#define DLT_JUNIPER_ES 132 -#define DLT_JUNIPER_GGSN 133 -#define DLT_JUNIPER_MFR 134 -#define DLT_JUNIPER_ATM2 135 -#define DLT_JUNIPER_SERVICES 136 -#define DLT_JUNIPER_ATM1 137 - -/* - * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund - * . The header that's presented is an Ethernet-like - * header: - * - * #define FIREWIRE_EUI64_LEN 8 - * struct firewire_header { - * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; - * u_char firewire_shost[FIREWIRE_EUI64_LEN]; - * u_short firewire_type; - * }; - * - * with "firewire_type" being an Ethernet type value, rather than, - * for example, raw GASP frames being handed up. - */ -#define DLT_APPLE_IP_OVER_IEEE1394 138 - -/* - * Various SS7 encapsulations, as per a request from Jeff Morriss - * and subsequent discussions. - */ -#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ -#define DLT_MTP2 140 /* MTP2, without pseudo-header */ -#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ -#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ - -/* - * Reserved for DOCSIS. - */ -#define DLT_DOCSIS 143 - -/* - * Reserved for Linux IrDA. - */ -#define DLT_LINUX_IRDA 144 - -/* - * Reserved for IBM SP switch and IBM Next Federation switch. - */ -#define DLT_IBM_SP 145 -#define DLT_IBM_SN 146 - -/* - * Reserved for private use. If you have some link-layer header type - * that you want to use within your organization, with the capture files - * using that link-layer header type not ever be sent outside your - * organization, you can use these values. - * - * No libpcap release will use these for any purpose, nor will any - * tcpdump release use them, either. - * - * Do *NOT* use these in capture files that you expect anybody not using - * your private versions of capture-file-reading tools to read; in - * particular, do *NOT* use them in products, otherwise you may find that - * people won't be able to use tcpdump, or snort, or Ethereal, or... to - * read capture files from your firewall/intrusion detection/traffic - * monitoring/etc. appliance, or whatever product uses that DLT_ value, - * and you may also find that the developers of those applications will - * not accept patches to let them read those files. - * - * Also, do not use them if somebody might send you a capture using them - * for *their* private type and tools using them for *your* private type - * would have to read them. - * - * Instead, ask "tcpdump-workers@tcpdump.org" for a new DLT_ value, - * as per the comment above, and use the type you're given. - */ -#define DLT_USER0 147 -#define DLT_USER1 148 -#define DLT_USER2 149 -#define DLT_USER3 150 -#define DLT_USER4 151 -#define DLT_USER5 152 -#define DLT_USER6 153 -#define DLT_USER7 154 -#define DLT_USER8 155 -#define DLT_USER9 156 -#define DLT_USER10 157 -#define DLT_USER11 158 -#define DLT_USER12 159 -#define DLT_USER13 160 -#define DLT_USER14 161 -#define DLT_USER15 162 - -/* - * For future use with 802.11 captures - defined by AbsoluteValue - * Systems to store a number of bits of link-layer information - * including radio information: - * - * http://www.shaftnet.org/~pizza/software/capturefrm.txt - * - * but it might be used by some non-AVS drivers now or in the - * future. - */ -#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, etc.. - */ -#define DLT_JUNIPER_MONITOR 164 - -/* - * Reserved for BACnet MS/TP. - */ -#define DLT_BACNET_MS_TP 165 - -/* - * Another PPP variant as per request from Karsten Keil . - * - * This is used in some OSes to allow a kernel socket filter to distinguish - * between incoming and outgoing packets, on a socket intended to - * supply pppd with outgoing packets so it can do dial-on-demand and - * hangup-on-lack-of-demand; incoming packets are filtered out so they - * don't cause pppd to hold the connection up (you don't want random - * input packets such as port scans, packets from old lost connections, - * etc. to force the connection to stay up). - * - * The first byte of the PPP header (0xff03) is modified to accommodate - * the direction - 0x00 = IN, 0x01 = OUT. - */ -#define DLT_PPP_PPPD 166 - -/* - * Names for backwards compatibility with older versions of some PPP - * software; new software should use DLT_PPP_PPPD. - */ -#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD -#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, cookies, etc.. - */ -#define DLT_JUNIPER_PPPOE 167 -#define DLT_JUNIPER_PPPOE_ATM 168 - -#define DLT_GPRS_LLC 169 /* GPRS LLC */ -#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ -#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ - -/* - * Requested by Oolan Zimmer for use in Gcom's T1/E1 line - * monitoring equipment. - */ -#define DLT_GCOM_T1E1 172 -#define DLT_GCOM_SERIAL 173 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . The DLT_ is used - * for internal communication to Physical Interface Cards (PIC) - */ -#define DLT_JUNIPER_PIC_PEER 174 - -/* - * Link types requested by Gregor Maier of Endace - * Measurement Systems. They add an ERF header (see - * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of - * the link-layer header. - */ -#define DLT_ERF_ETH 175 /* Ethernet */ -#define DLT_ERF_POS 176 /* Packet-over-SONET */ - -/* - * Requested by Daniele Orlandi for raw LAPD - * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header - * includes additional information before the LAPD header, so it's - * not necessarily a generic LAPD header. - */ -#define DLT_LINUX_LAPD 177 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ are used for prepending meta-information - * like interface index, interface name - * before standard Ethernet, PPP, Frelay & C-HDLC Frames - */ -#define DLT_JUNIPER_ETHER 178 -#define DLT_JUNIPER_PPP 179 -#define DLT_JUNIPER_FRELAY 180 -#define DLT_JUNIPER_CHDLC 181 - -/* - * Multi Link Frame Relay (FRF.16) - */ -#define DLT_MFR 182 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ is used for internal communication with a - * voice Adapter Card (PIC) - */ -#define DLT_JUNIPER_VP 183 - -/* - * Arinc 429 frames. - * DLT_ requested by Gianluca Varenni . - * Every frame contains a 32bit A429 label. - * More documentation on Arinc 429 can be found at - * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf - */ -#define DLT_A429 184 - -/* - * Arinc 653 Interpartition Communication messages. - * DLT_ requested by Gianluca Varenni . - * Please refer to the A653-1 standard for more information. - */ -#define DLT_A653_ICM 185 - -/* - * USB packets, beginning with a USB setup header; requested by - * Paolo Abeni . - */ -#define DLT_USB 186 - -/* - * Bluetooth HCI UART transport layer (part H:4); requested by - * Paolo Abeni. - */ -#define DLT_BLUETOOTH_HCI_H4 187 - -/* - * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz - * . - */ -#define DLT_IEEE802_16_MAC_CPS 188 - -/* - * USB packets, beginning with a Linux USB header; requested by - * Paolo Abeni . - */ -#define DLT_USB_LINUX 189 - -/* - * Controller Area Network (CAN) v. 2.0B packets. - * DLT_ requested by Gianluca Varenni . - * Used to dump CAN packets coming from a CAN Vector board. - * More documentation on the CAN v2.0B frames can be found at - * http://www.can-cia.org/downloads/?269 - */ -#define DLT_CAN20B 190 - -/* - * IEEE 802.15.4, with address fields padded, as is done by Linux - * drivers; requested by Juergen Schimmer. - */ -#define DLT_IEEE802_15_4_LINUX 191 - -/* - * Per Packet Information encapsulated packets. - * DLT_ requested by Gianluca Varenni . - */ -#define DLT_PPI 192 - -/* - * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; - * requested by Charles Clancy. - */ -#define DLT_IEEE802_16_MAC_CPS_RADIO 193 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ is used for internal communication with a - * integrated service module (ISM). - */ -#define DLT_JUNIPER_ISM 194 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing); requested by Mikko Saarnivala . - */ -#define DLT_IEEE802_15_4 195 - -/* - * Various link-layer types, with a pseudo-header, for SITA - * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). - */ -#define DLT_SITA 196 - -/* - * Various link-layer types, with a pseudo-header, for Endace DAG cards; - * encapsulates Endace ERF records. Requested by Stephen Donnelly - * . - */ -#define DLT_ERF 197 - -/* - * Special header prepended to Ethernet packets when capturing from a - * u10 Networks board. Requested by Phil Mulholland - * . - */ -#define DLT_RAIF1 198 - -/* - * IPMB packet for IPMI, beginning with the I2C slave address, followed - * by the netFn and LUN, etc.. Requested by Chanthy Toeung - * . - */ -#define DLT_IPMB 199 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ is used for capturing data on a secure tunnel interface. - */ -#define DLT_JUNIPER_ST 200 - -/* - * Bluetooth HCI UART transport layer (part H:4), with pseudo-header - * that includes direction information; requested by Paolo Abeni. - */ -#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 - -/* - * AX.25 packet with a 1-byte KISS header; see - * - * http://www.ax25.net/kiss.htm - * - * as per Richard Stearn . - */ -#define DLT_AX25_KISS 202 - -/* - * LAPD packets from an ISDN channel, starting with the address field, - * with no pseudo-header. - * Requested by Varuna De Silva . - */ -#define DLT_LAPD 203 - -/* - * Variants of various link-layer headers, with a one-byte direction - * pseudo-header prepended - zero means "received by this host", - * non-zero (any non-zero value) means "sent by this host" - as per - * Will Barker . - */ -#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ -#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ -#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ -#define DLT_LAPB_WITH_DIR 207 /* LAPB */ - -/* - * 208 is reserved for an as-yet-unspecified proprietary link-layer - * type, as requested by Will Barker. - */ - -/* - * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman - * . - */ -#define DLT_IPMB_LINUX 209 - -/* - * FlexRay automotive bus - http://www.flexray.com/ - as requested - * by Hannes Kaelber . - */ -#define DLT_FLEXRAY 210 - -/* - * Media Oriented Systems Transport (MOST) bus for multimedia - * transport - http://www.mostcooperation.com/ - as requested - * by Hannes Kaelber . - */ -#define DLT_MOST 211 - -/* - * Local Interconnect Network (LIN) bus for vehicle networks - - * http://www.lin-subbus.org/ - as requested by Hannes Kaelber - * . - */ -#define DLT_LIN 212 - -/* - * X2E-private data link type used for serial line capture, - * as requested by Hannes Kaelber . - */ -#define DLT_X2E_SERIAL 213 - -/* - * X2E-private data link type used for the Xoraya data logger - * family, as requested by Hannes Kaelber . - */ -#define DLT_X2E_XORAYA 214 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing), but with the PHY-level data for non-ASK PHYs (4 octets - * of 0 as preamble, one octet of SFD, one octet of frame length+ - * reserved bit, and then the MAC-layer data, starting with the - * frame control field). - * - * Requested by Max Filippov . - */ -#define DLT_IEEE802_15_4_NONASK_PHY 215 - -/* - * David Gibson requested this for - * captures from the Linux kernel /dev/input/eventN devices. This - * is used to communicate keystrokes and mouse movements from the - * Linux kernel to display systems, such as Xorg. - */ -#define DLT_LINUX_EVDEV 216 - -/* - * GSM Um and Abis interfaces, preceded by a "gsmtap" header. - * - * Requested by Harald Welte . - */ -#define DLT_GSMTAP_UM 217 -#define DLT_GSMTAP_ABIS 218 - -/* - * MPLS, with an MPLS label as the link-layer header. - * Requested by Michele Marchetto on behalf - * of OpenBSD. - */ -#define DLT_MPLS 219 - -/* - * USB packets, beginning with a Linux USB header, with the USB header - * padded to 64 bytes; required for memory-mapped access. - */ -#define DLT_USB_LINUX_MMAPPED 220 - -/* - * DECT packets, with a pseudo-header; requested by - * Matthias Wenzel . - */ -#define DLT_DECT 221 -/* - * From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" - * Date: Mon, 11 May 2009 11:18:30 -0500 - * - * DLT_AOS. We need it for AOS Space Data Link Protocol. - * I have already written dissectors for but need an OK from - * legal before I can submit a patch. - * - */ -#define DLT_AOS 222 - -/* - * Wireless HART (Highway Addressable Remote Transducer) - * From the HART Communication Foundation - * IES/PAS 62591 - * - * Requested by Sam Roberts . - */ -#define DLT_WIHART 223 - -/* - * Fibre Channel FC-2 frames, beginning with a Frame_Header. - * Requested by Kahou Lei . - */ -#define DLT_FC_2 224 - -/* - * Fibre Channel FC-2 frames, beginning with an encoding of the - * SOF, and ending with an encoding of the EOF. - * - * The encodings represent the frame delimiters as 4-byte sequences - * representing the corresponding ordered sets, with K28.5 - * represented as 0xBC, and the D symbols as the corresponding - * byte values; for example, SOFi2, which is K28.5 - D21.5 - D1.2 - D21.2, - * is represented as 0xBC 0xB5 0x55 0x55. - * - * Requested by Kahou Lei . - */ -#define DLT_FC_2_WITH_FRAME_DELIMS 225 -/* - * Solaris ipnet pseudo-header; requested by Darren Reed . - * - * The pseudo-header starts with a one-byte version number; for version 2, - * the pseudo-header is: - * - * struct dl_ipnetinfo { - * u_int8_t dli_version; - * u_int8_t dli_family; - * u_int16_t dli_htype; - * u_int32_t dli_pktlen; - * u_int32_t dli_ifindex; - * u_int32_t dli_grifindex; - * u_int32_t dli_zsrc; - * u_int32_t dli_zdst; - * }; - * - * dli_version is 2 for the current version of the pseudo-header. - * - * dli_family is a Solaris address family value, so it's 2 for IPv4 - * and 26 for IPv6. - * - * dli_htype is a "hook type" - 0 for incoming packets, 1 for outgoing - * packets, and 2 for packets arriving from another zone on the same - * machine. - * - * dli_pktlen is the length of the packet data following the pseudo-header - * (so the captured length minus dli_pktlen is the length of the - * pseudo-header, assuming the entire pseudo-header was captured). - * - * dli_ifindex is the interface index of the interface on which the - * packet arrived. - * - * dli_grifindex is the group interface index number (for IPMP interfaces). - * - * dli_zsrc is the zone identifier for the source of the packet. - * - * dli_zdst is the zone identifier for the destination of the packet. - * - * A zone number of 0 is the global zone; a zone number of 0xffffffff - * means that the packet arrived from another host on the network, not - * from another zone on the same machine. - * - * An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates - * which of those it is. - */ -#define DLT_IPNET 226 - -/* - * CAN (Controller Area Network) frames, with a pseudo-header as supplied - * by Linux SocketCAN. See Documentation/networking/can.txt in the Linux - * source. - * - * Requested by Felix Obenhuber . - */ -#define DLT_CAN_SOCKETCAN 227 - -/* - * Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies - * whether it's v4 or v6. Requested by Darren Reed . - */ -#define DLT_IPV4 228 -#define DLT_IPV6 229 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing), and with no FCS at the end of the frame; requested by - * Jon Smirl . - */ -#define DLT_IEEE802_15_4_NOFCS 230 - -/* - * Raw D-Bus: - * - * http://www.freedesktop.org/wiki/Software/dbus - * - * messages: - * - * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages - * - * starting with the endianness flag, followed by the message type, etc., - * but without the authentication handshake before the message sequence: - * - * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol - * - * Requested by Martin Vidner . - */ -#define DLT_DBUS 231 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - */ -#define DLT_JUNIPER_VS 232 -#define DLT_JUNIPER_SRX_E2E 233 -#define DLT_JUNIPER_FIBRECHANNEL 234 - -/* - * DVB-CI (DVB Common Interface for communication between a PC Card - * module and a DVB receiver). See - * - * http://www.kaiser.cx/pcap-dvbci.html - * - * for the specification. - * - * Requested by Martin Kaiser . - */ -#define DLT_DVB_CI 235 - -/* - * Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but - * *not* the same as, 27.010). Requested by Hans-Christoph Schemmel - * . - */ -#define DLT_MUX27010 236 - -/* - * STANAG 5066 D_PDUs. Requested by M. Baris Demiray - * . - */ -#define DLT_STANAG_5066_D_PDU 237 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - */ -#define DLT_JUNIPER_ATM_CEMIC 238 - -/* - * NetFilter LOG messages - * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets) - * - * Requested by Jakub Zawadzki - */ -#define DLT_NFLOG 239 - -/* - * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type - * for Ethernet packets with a 4-byte pseudo-header and always - * with the payload including the FCS, as supplied by their - * netANALYZER hardware and software. - * - * Requested by Holger P. Frommer - */ -#define DLT_NETANALYZER 240 - -/* - * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type - * for Ethernet packets with a 4-byte pseudo-header and FCS and - * with the Ethernet header preceded by 7 bytes of preamble and - * 1 byte of SFD, as supplied by their netANALYZER hardware and - * software. - * - * Requested by Holger P. Frommer - */ -#define DLT_NETANALYZER_TRANSPARENT 241 - -/* - * IP-over-InfiniBand, as specified by RFC 4391. - * - * Requested by Petr Sumbera . - */ -#define DLT_IPOIB 242 - -/* - * MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0). - * - * Requested by Guy Martin . - */ -#define DLT_MPEG_2_TS 243 - -/* - * ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as - * used by their ng40 protocol tester. - * - * Requested by Jens Grimmer . - */ -#define DLT_NG40 244 - -/* - * Pseudo-header giving adapter number and flags, followed by an NFC - * (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU, - * as specified by NFC Forum Logical Link Control Protocol Technical - * Specification LLCP 1.1. - * - * Requested by Mike Wakerly . - */ -#define DLT_NFC_LLCP 245 - -/* - * 245 is used as LINKTYPE_PFSYNC; do not use it for any other purpose. - * - * DLT_PFSYNC has different values on different platforms, and all of - * them collide with something used elsewhere. On platforms that - * don't already define it, define it as 245. - */ -//#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__APPLE__) -//#define DLT_PFSYNC 246 -//#endif - -/* - * Raw InfiniBand packets, starting with the Local Routing Header. - * - * Requested by Oren Kladnitsky . - */ -#define DLT_INFINIBAND 247 - -/* - * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6). - * - * Requested by Michael Tuexen . - */ -#define DLT_SCTP 248 - -/* - * USB packets, beginning with a USBPcap header. - * - * Requested by Tomasz Mon - */ -#define DLT_USBPCAP 249 - -/* - * Schweitzer Engineering Laboratories "RTAC" product serial-line - * packets. - * - * Requested by Chris Bontje . - */ -#define DLT_RTAC_SERIAL 250 - -/* - * Bluetooth Low Energy air interface link-layer packets. - * - * Requested by Mike Kershaw . - */ -#define DLT_BLUETOOTH_LE_LL 251 - -/* - * DLT type for upper-protocol layer PDU saves from wireshark. - * - * the actual contents are determined by two TAGs stored with each - * packet: - * EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the - * original packet. - * - * EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector - * that can make sense of the data stored. - */ -#define DLT_WIRESHARK_UPPER_PDU 252 - -/* - * DLT type for the netlink protocol (nlmon devices). - */ -#define DLT_NETLINK 253 - -/* - * Bluetooth Linux Monitor headers for the BlueZ stack. - */ -#define DLT_BLUETOOTH_LINUX_MONITOR 254 - -/* - * Bluetooth Basic Rate/Enhanced Data Rate baseband packets, as - * captured by Ubertooth. - */ -#define DLT_BLUETOOTH_BREDR_BB 255 - -/* - * Bluetooth Low Energy link layer packets, as captured by Ubertooth. - */ -#define DLT_BLUETOOTH_LE_LL_WITH_PHDR 256 - -/* - * PROFIBUS data link layer. - */ -#define DLT_PROFIBUS_DL 257 - -/* - * Apple's DLT_PKTAP headers. - * - * Sadly, the folks at Apple either had no clue that the DLT_USERn values - * are for internal use within an organization and partners only, and - * didn't know that the right way to get a link-layer header type is to - * ask tcpdump.org for one, or knew and didn't care, so they just - * used DLT_USER2, which causes problems for everything except for - * their version of tcpdump. - * - * So I'll just give them one; hopefully this will show up in a - * libpcap release in time for them to get this into 10.10 Big Sur - * or whatever Mavericks' successor is called. LINKTYPE_PKTAP - * will be 258 *even on OS X*; that is *intentional*, so that - * PKTAP files look the same on *all* OSes (different OSes can have - * different numerical values for a given DLT_, but *MUST NOT* have - * different values for what goes in a file, as files can be moved - * between OSes!). - * - * When capturing, on a system with a Darwin-based OS, on a device - * that returns 149 (DLT_USER2 and Apple's DLT_PKTAP) with this - * version of libpcap, the DLT_ value for the pcap_t will be DLT_PKTAP, - * and that will continue to be DLT_USER2 on Darwin-based OSes. That way, - * binary compatibility with Mavericks is preserved for programs using - * this version of libpcap. This does mean that if you were using - * DLT_USER2 for some capture device on OS X, you can't do so with - * this version of libpcap, just as you can't with Apple's libpcap - - * on OS X, they define DLT_PKTAP to be DLT_USER2, so programs won't - * be able to distinguish between PKTAP and whatever you were using - * DLT_USER2 for. - * - * If the program saves the capture to a file using this version of - * libpcap's pcap_dump code, the LINKTYPE_ value in the file will be - * LINKTYPE_PKTAP, which will be 258, even on Darwin-based OSes. - * That way, the file will *not* be a DLT_USER2 file. That means - * that the latest version of tcpdump, when built with this version - * of libpcap, and sufficiently recent versions of Wireshark will - * be able to read those files and interpret them correctly; however, - * Apple's version of tcpdump in OS X 10.9 won't be able to handle - * them. (Hopefully, Apple will pick up this version of libpcap, - * and the corresponding version of tcpdump, so that tcpdump will - * be able to handle the old LINKTYPE_USER2 captures *and* the new - * LINKTYPE_PKTAP captures.) - */ -#ifdef __APPLE__ -#define DLT_PKTAP DLT_USER2 -#else -#define DLT_PKTAP 258 -#endif - -/* - * Ethernet packets preceded by a header giving the last 6 octets - * of the preamble specified by 802.3-2012 Clause 65, section - * 65.1.3.2 "Transmit". - */ -#define DLT_EPON 259 - -/* - * IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" - * in the PICMG HPM.2 specification. - */ -#define DLT_IPMI_HPM_2 260 - -#define DLT_MATCHING_MAX 260 /* highest value in the "matching" range */ - -/* - * DLT and savefile link type values are split into a class and - * a member of that class. A class value of 0 indicates a regular - * DLT_/LINKTYPE_ value. - */ -#define DLT_CLASS(x) ((x) & 0x03ff0000) - /* * The instruction encodings. * @@ -1455,10 +409,11 @@ SYSCTL_DECL(_net_bpf); * bpf_peers_present() calls. */ struct bpf_if; +CK_LIST_HEAD(bpfd_list, bpf_d); struct bpf_if_ext { - LIST_ENTRY(bpf_if) bif_next; /* list of all interfaces */ - LIST_HEAD(, bpf_d) bif_dlist; /* descriptor list */ + CK_LIST_ENTRY(bpf_if) bif_next; /* list of all interfaces */ + struct bpfd_list bif_dlist; /* descriptor list */ }; void bpf_bufheld(struct bpf_d *d); @@ -1482,7 +437,7 @@ bpf_peers_present(struct bpf_if *bpf) struct bpf_if_ext *ext; ext = (struct bpf_if_ext *)bpf; - if (!LIST_EMPTY(&ext->bif_dlist)) + if (!CK_LIST_EMPTY(&ext->bif_dlist)) return (1); return (0); } diff --git a/tools/compat/include/net/bpfdesc.h b/tools/compat/include/net/bpfdesc.h index 6fda8d6a5..8e3ab5ca6 100644 --- a/tools/compat/include/net/bpfdesc.h +++ b/tools/compat/include/net/bpfdesc.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1990, 1991, 1993 * The Regents of the University of California. All rights reserved. * @@ -15,7 +17,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -41,7 +43,9 @@ #include #include -#include +#include +#include +#include #include /* @@ -49,7 +53,7 @@ */ struct zbuf; struct bpf_d { - LIST_ENTRY(bpf_d) bd_next; /* Linked list of descriptors */ + CK_LIST_ENTRY(bpf_d) bd_next; /* Linked list of descriptors */ /* * Buffer slots: two memory buffers store the incoming packets. * The model has three slots. Sbuf is always occupied. @@ -73,8 +77,8 @@ struct bpf_d { struct bpf_insn *bd_rfilter; /* read filter code */ struct bpf_insn *bd_wfilter; /* write filter code */ void *bd_bfilter; /* binary filter code */ - u_int64_t bd_rcount; /* number of packets received */ - u_int64_t bd_dcount; /* number of packets dropped */ + counter_u64_t bd_rcount; /* number of packets received */ + counter_u64_t bd_dcount; /* number of packets dropped */ u_char bd_promisc; /* true if listening promiscuously */ u_char bd_state; /* idle, waiting, or timed out */ @@ -91,15 +95,18 @@ struct bpf_d { struct mtx bd_lock; /* per-descriptor lock */ struct callout bd_callout; /* for BPF timeouts with select */ struct label *bd_label; /* MAC label for descriptor */ - u_int64_t bd_fcount; /* number of packets which matched filter */ + counter_u64_t bd_fcount; /* number of packets which matched filter */ pid_t bd_pid; /* PID which created descriptor */ int bd_locked; /* true if descriptor is locked */ u_int bd_bufmode; /* Current buffer mode. */ - u_int64_t bd_wcount; /* number of packets written */ - u_int64_t bd_wfcount; /* number of packets that matched write filter */ - u_int64_t bd_wdcount; /* number of packets dropped during a write */ - u_int64_t bd_zcopy; /* number of zero copy operations */ + counter_u64_t bd_wcount; /* number of packets written */ + counter_u64_t bd_wfcount; /* number of packets that matched write filter */ + counter_u64_t bd_wdcount; /* number of packets dropped during a write */ + counter_u64_t bd_zcopy; /* number of zero copy operations */ u_char bd_compat32; /* 32-bit stream on LP64 system */ + + volatile u_int bd_refcnt; + struct epoch_context epoch_ctx; }; /* Values for bd_state */ @@ -114,9 +121,6 @@ struct bpf_d { #define BPF_PID_REFRESH(bd, td) (bd)->bd_pid = (td)->td_proc->p_pid #define BPF_PID_REFRESH_CUR(bd) (bd)->bd_pid = curthread->td_proc->p_pid -#define BPF_LOCK() mtx_lock(&bpf_mtx) -#define BPF_UNLOCK() mtx_unlock(&bpf_mtx) -#define BPF_LOCK_ASSERT() mtx_assert(&bpf_mtx, MA_OWNED) /* * External representation of the bpf descriptor */ @@ -151,11 +155,6 @@ struct xbpf_d { u_int64_t bd_spare[4]; }; -#define BPFIF_RLOCK(bif) rw_rlock(&(bif)->bif_lock) -#define BPFIF_RUNLOCK(bif) rw_runlock(&(bif)->bif_lock) -#define BPFIF_WLOCK(bif) rw_wlock(&(bif)->bif_lock) -#define BPFIF_WUNLOCK(bif) rw_wunlock(&(bif)->bif_lock) - #define BPFIF_FLAG_DYING 1 /* Reject new bpf consumers */ #endif diff --git a/tools/compat/include/net/dlt.h b/tools/compat/include/net/dlt.h new file mode 100644 index 000000000..31ad4e010 --- /dev/null +++ b/tools/compat/include/net/dlt.h @@ -0,0 +1,1412 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)bpf.h 7.1 (Berkeley) 5/7/91 + * + * $FreeBSD$ + */ + +#ifndef _NET_DLT_H_ +#define _NET_DLT_H_ + +/* + * Link-layer header type codes. + * + * Do *NOT* add new values to this list without asking + * "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run + * the risk of using a value that's already being used for some other + * purpose, and of having tools that read libpcap-format captures not + * being able to handle captures with your new DLT_ value, with no hope + * that they will ever be changed to do so (as that would destroy their + * ability to read captures using that value for that other purpose). + * + * See + * + * http://www.tcpdump.org/linktypes.html + * + * for detailed descriptions of some of these link-layer header types. + */ + +/* + * These are the types that are the same on all platforms, and that + * have been defined by for ages. + */ +#define DLT_NULL 0 /* BSD loopback encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* 802.5 Token Ring */ +#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ + +/* + * These are types that are different on some platforms, and that + * have been defined by for ages. We use #ifdefs to + * detect the BSDs that define them differently from the traditional + * libpcap + * + * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, + * but I don't know what the right #define is for BSD/OS. + */ +#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ + +#ifdef __OpenBSD__ +#define DLT_RAW 14 /* raw IP */ +#else +#define DLT_RAW 12 /* raw IP */ +#endif + +/* + * Given that the only OS that currently generates BSD/OS SLIP or PPP + * is, well, BSD/OS, arguably everybody should have chosen its values + * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they + * didn't. So it goes. + */ +#if defined(__NetBSD__) || defined(__FreeBSD__) +#ifndef DLT_SLIP_BSDOS +#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ +#endif +#else +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ +#endif + +/* + * 17 was used for DLT_PFLOG in OpenBSD; it no longer is. + * + * It was DLT_LANE8023 in SuSE 6.3, so we defined LINKTYPE_PFLOG + * as 117 so that pflog captures would use a link-layer header type + * value that didn't collide with any other values. On all + * platforms other than OpenBSD, we defined DLT_PFLOG as 117, + * and we mapped between LINKTYPE_PFLOG and DLT_PFLOG. + * + * OpenBSD eventually switched to using 117 for DLT_PFLOG as well. + * + * Don't use 17 for anything else. + */ + +/* + * 18 is used for DLT_PFSYNC in OpenBSD, NetBSD, DragonFly BSD and + * macOS; don't use it for anything else. (FreeBSD uses 121, which + * collides with DLT_HHDLC, even though it doesn't use 18 for + * anything and doesn't appear to have ever used it for anything.) + * + * We define it as 18 on those platforms; it is, unfortunately, used + * for DLT_CIP in Suse 6.3, so we don't define it as DLT_PFSYNC + * in general. As the packet format for it, like that for + * DLT_PFLOG, is not only OS-dependent but OS-version-dependent, + * we don't support printing it in tcpdump except on OSes that + * have the relevant header files, so it's not that useful on + * other platforms. + */ +#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__) +#define DLT_PFSYNC 18 +#endif + +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + +/* + * Apparently Redback uses this for its SmartEdge 400/800. I hope + * nobody else decided to use it, too. + */ +#define DLT_REDBACK_SMARTEDGE 32 + +/* + * These values are defined by NetBSD; other platforms should refrain from + * using them for other purposes, so that NetBSD savefiles with link + * types of 50 or 51 can be read as this type on all platforms. + */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ +#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + +/* + * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses + * a link-layer type of 99 for the tcpdump it supplies. The link-layer + * header has 6 bytes of unknown data, something that appears to be an + * Ethernet type, and 36 bytes that appear to be 0 in at least one capture + * I've seen. + */ +#define DLT_SYMANTEC_FIREWALL 99 + +/* + * Values between 100 and 103 are used in capture file headers as + * link-layer header type LINKTYPE_ values corresponding to DLT_ types + * that differ between platforms; don't use those values for new DLT_ + * new types. + */ + +/* + * Values starting with 104 are used for newly-assigned link-layer + * header type values; for those link-layer header types, the DLT_ + * value returned by pcap_datalink() and passed to pcap_open_dead(), + * and the LINKTYPE_ value that appears in capture files, are the + * same. + * + * DLT_MATCHING_MIN is the lowest such value; DLT_MATCHING_MAX is + * the highest such value. + */ +#define DLT_MATCHING_MIN 104 + +/* + * This value was defined by libpcap 0.5; platforms that have defined + * it with a different value should define it here with that value - + * a link type of 104 in a save file will be mapped to DLT_C_HDLC, + * whatever value that happens to be, so programs will correctly + * handle files with that link type regardless of the value of + * DLT_C_HDLC. + * + * The name DLT_C_HDLC was used by BSD/OS; we use that name for source + * compatibility with programs written for BSD/OS. + * + * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, + * for source compatibility with programs written for libpcap 0.5. + */ +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC + +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + +/* + * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, + * except when it isn't. (I.e., sometimes it's just raw IP, and + * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, + * so that we don't have to worry about the link-layer header.) + */ + +/* + * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides + * with other values. + * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header + * (DLCI, etc.). + */ +#define DLT_FRELAY 107 + +/* + * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except + * that the AF_ type in the link-layer header is in network byte order. + * + * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so + * we don't use 12 for it in OSes other than OpenBSD. + */ +#ifdef __OpenBSD__ +#define DLT_LOOP 12 +#else +#define DLT_LOOP 108 +#endif + +/* + * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's + * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other + * than OpenBSD. + */ +#ifdef __OpenBSD__ +#define DLT_ENC 13 +#else +#define DLT_ENC 109 +#endif + +/* + * Values between 110 and 112 are reserved for use in capture file headers + * as link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ types + * other than the corresponding DLT_ types. + */ + +/* + * This is for Linux cooked sockets. + */ +#define DLT_LINUX_SLL 113 + +/* + * Apple LocalTalk hardware. + */ +#define DLT_LTALK 114 + +/* + * Acorn Econet. + */ +#define DLT_ECONET 115 + +/* + * Reserved for use with OpenBSD ipfilter. + */ +#define DLT_IPFILTER 116 + +/* + * OpenBSD DLT_PFLOG. + */ +#define DLT_PFLOG 117 + +/* + * Registered for Cisco-internal use. + */ +#define DLT_CISCO_IOS 118 + +/* + * For 802.11 cards using the Prism II chips, with a link-layer + * header including Prism monitor mode information plus an 802.11 + * header. + */ +#define DLT_PRISM_HEADER 119 + +/* + * Reserved for Aironet 802.11 cards, with an Aironet link-layer header + * (see Doug Ambrisko's FreeBSD patches). + */ +#define DLT_AIRONET_HEADER 120 + +/* + * Sigh. + * + * 121 was reserved for Siemens HiPath HDLC on 2002-01-25, as + * requested by Tomas Kukosa. + * + * On 2004-02-25, a FreeBSD checkin to sys/net/bpf.h was made that + * assigned 121 as DLT_PFSYNC. In current versions, its libpcap + * does DLT_ <-> LINKTYPE_ mapping, mapping DLT_PFSYNC to a + * LINKTYPE_PFSYNC value of 246, so it should write out DLT_PFSYNC + * dump files with 246 as the link-layer header type. (Earlier + * versions might not have done mapping, in which case they would + * have written them out with a link-layer header type of 121.) + * + * OpenBSD, from which pf came, however, uses 18 for DLT_PFSYNC; + * its libpcap does no DLT_ <-> LINKTYPE_ mapping, so it would + * write out DLT_PFSYNC dump files with use 18 as the link-layer + * header type. + * + * NetBSD, DragonFly BSD, and Darwin also use 18 for DLT_PFSYNC; in + * current versions, their libpcaps do DLT_ <-> LINKTYPE_ mapping, + * mapping DLT_PFSYNC to a LINKTYPE_PFSYNC value of 246, so they + * should write out DLT_PFSYNC dump files with 246 as the link-layer + * header type. (Earlier versions might not have done mapping, + * in which case they'd work the same way OpenBSD does, writing + * them out with a link-layer header type of 18.) + * + * We'll define DLT_PFSYNC as: + * + * 18 on NetBSD, OpenBSD, DragonFly BSD, and Darwin; + * + * 121 on FreeBSD; + * + * 246 everywhere else. + * + * We'll define DLT_HHDLC as 121 on everything except for FreeBSD; + * anybody who wants to compile, on FreeBSD, code that uses DLT_HHDLC + * is out of luck. + * + * We'll define LINKTYPE_PFSYNC as 246 on *all* platforms, so that + * savefiles written using *this* code won't use 18 or 121 for PFSYNC, + * they'll all use 246. + * + * Code that uses pcap_datalink() to determine the link-layer header + * type of a savefile won't, when built and run on FreeBSD, be able + * to distinguish between LINKTYPE_PFSYNC and LINKTYPE_HHDLC capture + * files, as pcap_datalink() will give 121 for both of them. Code + * that doesn't, such as the code in Wireshark, will be able to + * distinguish between them. + * + * FreeBSD's libpcap won't map a link-layer header type of 18 - i.e., + * DLT_PFSYNC files from OpenBSD and possibly older versions of NetBSD, + * DragonFly BSD, and macOS - to DLT_PFSYNC, so code built with FreeBSD's + * libpcap won't treat those files as DLT_PFSYNC files. + * + * Other libpcaps won't map a link-layer header type of 121 to DLT_PFSYNC; + * this means they can read DLT_HHDLC files, if any exist, but won't + * treat pcap files written by any older versions of FreeBSD libpcap that + * didn't map to 246 as DLT_PFSYNC files. + */ +#ifdef __FreeBSD__ +#define DLT_PFSYNC 121 +#else +#define DLT_HHDLC 121 +#endif + +/* + * This is for RFC 2625 IP-over-Fibre Channel. + * + * This is not for use with raw Fibre Channel, where the link-layer + * header starts with a Fibre Channel frame header; it's for IP-over-FC, + * where the link-layer header starts with an RFC 2625 Network_Header + * field. + */ +#define DLT_IP_OVER_FC 122 + +/* + * This is for Full Frontal ATM on Solaris with SunATM, with a + * pseudo-header followed by an AALn PDU. + * + * There may be other forms of Full Frontal ATM on other OSes, + * with different pseudo-headers. + * + * If ATM software returns a pseudo-header with VPI/VCI information + * (and, ideally, packet type information, e.g. signalling, ILMI, + * LANE, LLC-multiplexed traffic, etc.), it should not use + * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump + * and the like don't have to infer the presence or absence of a + * pseudo-header and the form of the pseudo-header. + */ +#define DLT_SUNATM 123 /* Solaris+SunATM */ + +/* + * Reserved as per request from Kent Dahlgren + * for private use. + */ +#define DLT_RIO 124 /* RapidIO */ +#define DLT_PCI_EXP 125 /* PCI Express */ +#define DLT_AURORA 126 /* Xilinx Aurora link layer */ + +/* + * Header for 802.11 plus a number of bits of link-layer information + * including radio information, used by some recent BSD drivers as + * well as the madwifi Atheros driver for Linux. + */ +#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ + +/* + * Reserved for the TZSP encapsulation, as per request from + * Chris Waters + * TZSP is a generic encapsulation for any other link type, + * which includes a means to include meta-information + * with the packet, e.g. signal strength and channel + * for 802.11 packets. + */ +#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ + +/* + * BSD's ARCNET headers have the source host, destination host, + * and type at the beginning of the packet; that's what's handed + * up to userland via BPF. + * + * Linux's ARCNET headers, however, have a 2-byte offset field + * between the host IDs and the type; that's what's handed up + * to userland via PF_PACKET sockets. + * + * We therefore have to have separate DLT_ values for them. + */ +#define DLT_ARCNET_LINUX 129 /* ARCNET */ + +/* + * Juniper-private data link types, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MLPPP 130 +#define DLT_JUNIPER_MLFR 131 +#define DLT_JUNIPER_ES 132 +#define DLT_JUNIPER_GGSN 133 +#define DLT_JUNIPER_MFR 134 +#define DLT_JUNIPER_ATM2 135 +#define DLT_JUNIPER_SERVICES 136 +#define DLT_JUNIPER_ATM1 137 + +/* + * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund + * . The header that's presented is an Ethernet-like + * header: + * + * #define FIREWIRE_EUI64_LEN 8 + * struct firewire_header { + * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; + * u_char firewire_shost[FIREWIRE_EUI64_LEN]; + * u_short firewire_type; + * }; + * + * with "firewire_type" being an Ethernet type value, rather than, + * for example, raw GASP frames being handed up. + */ +#define DLT_APPLE_IP_OVER_IEEE1394 138 + +/* + * Various SS7 encapsulations, as per a request from Jeff Morriss + * and subsequent discussions. + */ +#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ +#define DLT_MTP2 140 /* MTP2, without pseudo-header */ +#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ +#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ + +/* + * DOCSIS MAC frames. + */ +#define DLT_DOCSIS 143 + +/* + * Linux-IrDA packets. Protocol defined at http://www.irda.org. + * Those packets include IrLAP headers and above (IrLMP...), but + * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy + * framing can be handled by the hardware and depend on the bitrate. + * This is exactly the format you would get capturing on a Linux-IrDA + * interface (irdaX), but not on a raw serial port. + * Note the capture is done in "Linux-cooked" mode, so each packet include + * a fake packet header (struct sll_header). This is because IrDA packet + * decoding is dependant on the direction of the packet (incomming or + * outgoing). + * When/if other platform implement IrDA capture, we may revisit the + * issue and define a real DLT_IRDA... + * Jean II + */ +#define DLT_LINUX_IRDA 144 + +/* + * Reserved for IBM SP switch and IBM Next Federation switch. + */ +#define DLT_IBM_SP 145 +#define DLT_IBM_SN 146 + +/* + * Reserved for private use. If you have some link-layer header type + * that you want to use within your organization, with the capture files + * using that link-layer header type not ever be sent outside your + * organization, you can use these values. + * + * No libpcap release will use these for any purpose, nor will any + * tcpdump release use them, either. + * + * Do *NOT* use these in capture files that you expect anybody not using + * your private versions of capture-file-reading tools to read; in + * particular, do *NOT* use them in products, otherwise you may find that + * people won't be able to use tcpdump, or snort, or Ethereal, or... to + * read capture files from your firewall/intrusion detection/traffic + * monitoring/etc. appliance, or whatever product uses that DLT_ value, + * and you may also find that the developers of those applications will + * not accept patches to let them read those files. + * + * Also, do not use them if somebody might send you a capture using them + * for *their* private type and tools using them for *your* private type + * would have to read them. + * + * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, + * as per the comment above, and use the type you're given. + */ +#define DLT_USER0 147 +#define DLT_USER1 148 +#define DLT_USER2 149 +#define DLT_USER3 150 +#define DLT_USER4 151 +#define DLT_USER5 152 +#define DLT_USER6 153 +#define DLT_USER7 154 +#define DLT_USER8 155 +#define DLT_USER9 156 +#define DLT_USER10 157 +#define DLT_USER11 158 +#define DLT_USER12 159 +#define DLT_USER13 160 +#define DLT_USER14 161 +#define DLT_USER15 162 + +/* + * For future use with 802.11 captures - defined by AbsoluteValue + * Systems to store a number of bits of link-layer information + * including radio information: + * + * http://www.shaftnet.org/~pizza/software/capturefrm.txt + * + * but it might be used by some non-AVS drivers now or in the + * future. + */ +#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MONITOR 164 + +/* + * BACnet MS/TP frames. + */ +#define DLT_BACNET_MS_TP 165 + +/* + * Another PPP variant as per request from Karsten Keil . + * + * This is used in some OSes to allow a kernel socket filter to distinguish + * between incoming and outgoing packets, on a socket intended to + * supply pppd with outgoing packets so it can do dial-on-demand and + * hangup-on-lack-of-demand; incoming packets are filtered out so they + * don't cause pppd to hold the connection up (you don't want random + * input packets such as port scans, packets from old lost connections, + * etc. to force the connection to stay up). + * + * The first byte of the PPP header (0xff03) is modified to accomodate + * the direction - 0x00 = IN, 0x01 = OUT. + */ +#define DLT_PPP_PPPD 166 + +/* + * Names for backwards compatibility with older versions of some PPP + * software; new software should use DLT_PPP_PPPD. + */ +#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD +#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, cookies, etc.. + */ +#define DLT_JUNIPER_PPPOE 167 +#define DLT_JUNIPER_PPPOE_ATM 168 + +#define DLT_GPRS_LLC 169 /* GPRS LLC */ +#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ +#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ + +/* + * Requested by Oolan Zimmer for use in Gcom's T1/E1 line + * monitoring equipment. + */ +#define DLT_GCOM_T1E1 172 +#define DLT_GCOM_SERIAL 173 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_ is used + * for internal communication to Physical Interface Cards (PIC) + */ +#define DLT_JUNIPER_PIC_PEER 174 + +/* + * Link types requested by Gregor Maier of Endace + * Measurement Systems. They add an ERF header (see + * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of + * the link-layer header. + */ +#define DLT_ERF_ETH 175 /* Ethernet */ +#define DLT_ERF_POS 176 /* Packet-over-SONET */ + +/* + * Requested by Daniele Orlandi for raw LAPD + * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header + * includes additional information before the LAPD header, so it's + * not necessarily a generic LAPD header. + */ +#define DLT_LINUX_LAPD 177 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ are used for prepending meta-information + * like interface index, interface name + * before standard Ethernet, PPP, Frelay & C-HDLC Frames + */ +#define DLT_JUNIPER_ETHER 178 +#define DLT_JUNIPER_PPP 179 +#define DLT_JUNIPER_FRELAY 180 +#define DLT_JUNIPER_CHDLC 181 + +/* + * Multi Link Frame Relay (FRF.16) + */ +#define DLT_MFR 182 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for internal communication with a + * voice Adapter Card (PIC) + */ +#define DLT_JUNIPER_VP 183 + +/* + * Arinc 429 frames. + * DLT_ requested by Gianluca Varenni . + * Every frame contains a 32bit A429 label. + * More documentation on Arinc 429 can be found at + * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf + */ +#define DLT_A429 184 + +/* + * Arinc 653 Interpartition Communication messages. + * DLT_ requested by Gianluca Varenni . + * Please refer to the A653-1 standard for more information. + */ +#define DLT_A653_ICM 185 + +/* + * This used to be "USB packets, beginning with a USB setup header; + * requested by Paolo Abeni ." + * + * However, that header didn't work all that well - it left out some + * useful information - and was abandoned in favor of the DLT_USB_LINUX + * header. + * + * This is now used by FreeBSD for its BPF taps for USB; that has its + * own headers. So it is written, so it is done. + * + * For source-code compatibility, we also define DLT_USB to have this + * value. We do it numerically so that, if code that includes this + * file (directly or indirectly) also includes an OS header that also + * defines DLT_USB as 186, we don't get a redefinition warning. + * (NetBSD 7 does that.) + */ +#define DLT_USB_FREEBSD 186 +#define DLT_USB 186 + +/* + * Bluetooth HCI UART transport layer (part H:4); requested by + * Paolo Abeni. + */ +#define DLT_BLUETOOTH_HCI_H4 187 + +/* + * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz + * . + */ +#define DLT_IEEE802_16_MAC_CPS 188 + +/* + * USB packets, beginning with a Linux USB header; requested by + * Paolo Abeni . + */ +#define DLT_USB_LINUX 189 + +/* + * Controller Area Network (CAN) v. 2.0B packets. + * DLT_ requested by Gianluca Varenni . + * Used to dump CAN packets coming from a CAN Vector board. + * More documentation on the CAN v2.0B frames can be found at + * http://www.can-cia.org/downloads/?269 + */ +#define DLT_CAN20B 190 + +/* + * IEEE 802.15.4, with address fields padded, as is done by Linux + * drivers; requested by Juergen Schimmer. + */ +#define DLT_IEEE802_15_4_LINUX 191 + +/* + * Per Packet Information encapsulated packets. + * DLT_ requested by Gianluca Varenni . + */ +#define DLT_PPI 192 + +/* + * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; + * requested by Charles Clancy. + */ +#define DLT_IEEE802_16_MAC_CPS_RADIO 193 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for internal communication with a + * integrated service module (ISM). + */ +#define DLT_JUNIPER_ISM 194 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing); requested by Mikko Saarnivala . + * For this one, we expect the FCS to be present at the end of the frame; + * if the frame has no FCS, DLT_IEEE802_15_4_NOFCS should be used. + */ +#define DLT_IEEE802_15_4 195 + +/* + * Various link-layer types, with a pseudo-header, for SITA + * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). + */ +#define DLT_SITA 196 + +/* + * Various link-layer types, with a pseudo-header, for Endace DAG cards; + * encapsulates Endace ERF records. Requested by Stephen Donnelly + * . + */ +#define DLT_ERF 197 + +/* + * Special header prepended to Ethernet packets when capturing from a + * u10 Networks board. Requested by Phil Mulholland + * . + */ +#define DLT_RAIF1 198 + +/* + * IPMB packet for IPMI, beginning with the I2C slave address, followed + * by the netFn and LUN, etc.. Requested by Chanthy Toeung + * . + * + * XXX - this used to be called DLT_IPMB, back when we got the + * impression from the email thread requesting it that the packet + * had no extra 2-byte header. We've renamed it; if anybody used + * DLT_IPMB and assumed no 2-byte header, this will cause the compile + * to fail, at which point we'll have to figure out what to do about + * the two header types using the same DLT_/LINKTYPE_ value. If that + * doesn't happen, we'll assume nobody used it and that the redefinition + * is safe. + */ +#define DLT_IPMB_KONTRON 199 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for capturing data on a secure tunnel interface. + */ +#define DLT_JUNIPER_ST 200 + +/* + * Bluetooth HCI UART transport layer (part H:4), with pseudo-header + * that includes direction information; requested by Paolo Abeni. + */ +#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 + +/* + * AX.25 packet with a 1-byte KISS header; see + * + * http://www.ax25.net/kiss.htm + * + * as per Richard Stearn . + */ +#define DLT_AX25_KISS 202 + +/* + * LAPD packets from an ISDN channel, starting with the address field, + * with no pseudo-header. + * Requested by Varuna De Silva . + */ +#define DLT_LAPD 203 + +/* + * Variants of various link-layer headers, with a one-byte direction + * pseudo-header prepended - zero means "received by this host", + * non-zero (any non-zero value) means "sent by this host" - as per + * Will Barker . + */ +#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ +#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ +#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ +#define DLT_LAPB_WITH_DIR 207 /* LAPB */ + +/* + * 208 is reserved for an as-yet-unspecified proprietary link-layer + * type, as requested by Will Barker. + */ + +/* + * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman + * . + */ +#define DLT_IPMB_LINUX 209 + +/* + * FlexRay automotive bus - http://www.flexray.com/ - as requested + * by Hannes Kaelber . + */ +#define DLT_FLEXRAY 210 + +/* + * Media Oriented Systems Transport (MOST) bus for multimedia + * transport - http://www.mostcooperation.com/ - as requested + * by Hannes Kaelber . + */ +#define DLT_MOST 211 + +/* + * Local Interconnect Network (LIN) bus for vehicle networks - + * http://www.lin-subbus.org/ - as requested by Hannes Kaelber + * . + */ +#define DLT_LIN 212 + +/* + * X2E-private data link type used for serial line capture, + * as requested by Hannes Kaelber . + */ +#define DLT_X2E_SERIAL 213 + +/* + * X2E-private data link type used for the Xoraya data logger + * family, as requested by Hannes Kaelber . + */ +#define DLT_X2E_XORAYA 214 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing), but with the PHY-level data for non-ASK PHYs (4 octets + * of 0 as preamble, one octet of SFD, one octet of frame length+ + * reserved bit, and then the MAC-layer data, starting with the + * frame control field). + * + * Requested by Max Filippov . + */ +#define DLT_IEEE802_15_4_NONASK_PHY 215 + +/* + * David Gibson requested this for + * captures from the Linux kernel /dev/input/eventN devices. This + * is used to communicate keystrokes and mouse movements from the + * Linux kernel to display systems, such as Xorg. + */ +#define DLT_LINUX_EVDEV 216 + +/* + * GSM Um and Abis interfaces, preceded by a "gsmtap" header. + * + * Requested by Harald Welte . + */ +#define DLT_GSMTAP_UM 217 +#define DLT_GSMTAP_ABIS 218 + +/* + * MPLS, with an MPLS label as the link-layer header. + * Requested by Michele Marchetto on behalf + * of OpenBSD. + */ +#define DLT_MPLS 219 + +/* + * USB packets, beginning with a Linux USB header, with the USB header + * padded to 64 bytes; required for memory-mapped access. + */ +#define DLT_USB_LINUX_MMAPPED 220 + +/* + * DECT packets, with a pseudo-header; requested by + * Matthias Wenzel . + */ +#define DLT_DECT 221 + +/* + * From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" + * Date: Mon, 11 May 2009 11:18:30 -0500 + * + * DLT_AOS. We need it for AOS Space Data Link Protocol. + * I have already written dissectors for but need an OK from + * legal before I can submit a patch. + * + */ +#define DLT_AOS 222 + +/* + * Wireless HART (Highway Addressable Remote Transducer) + * From the HART Communication Foundation + * IES/PAS 62591 + * + * Requested by Sam Roberts . + */ +#define DLT_WIHART 223 + +/* + * Fibre Channel FC-2 frames, beginning with a Frame_Header. + * Requested by Kahou Lei . + */ +#define DLT_FC_2 224 + +/* + * Fibre Channel FC-2 frames, beginning with an encoding of the + * SOF, and ending with an encoding of the EOF. + * + * The encodings represent the frame delimiters as 4-byte sequences + * representing the corresponding ordered sets, with K28.5 + * represented as 0xBC, and the D symbols as the corresponding + * byte values; for example, SOFi2, which is K28.5 - D21.5 - D1.2 - D21.2, + * is represented as 0xBC 0xB5 0x55 0x55. + * + * Requested by Kahou Lei . + */ +#define DLT_FC_2_WITH_FRAME_DELIMS 225 + +/* + * Solaris ipnet pseudo-header; requested by Darren Reed . + * + * The pseudo-header starts with a one-byte version number; for version 2, + * the pseudo-header is: + * + * struct dl_ipnetinfo { + * uint8_t dli_version; + * uint8_t dli_family; + * uint16_t dli_htype; + * uint32_t dli_pktlen; + * uint32_t dli_ifindex; + * uint32_t dli_grifindex; + * uint32_t dli_zsrc; + * uint32_t dli_zdst; + * }; + * + * dli_version is 2 for the current version of the pseudo-header. + * + * dli_family is a Solaris address family value, so it's 2 for IPv4 + * and 26 for IPv6. + * + * dli_htype is a "hook type" - 0 for incoming packets, 1 for outgoing + * packets, and 2 for packets arriving from another zone on the same + * machine. + * + * dli_pktlen is the length of the packet data following the pseudo-header + * (so the captured length minus dli_pktlen is the length of the + * pseudo-header, assuming the entire pseudo-header was captured). + * + * dli_ifindex is the interface index of the interface on which the + * packet arrived. + * + * dli_grifindex is the group interface index number (for IPMP interfaces). + * + * dli_zsrc is the zone identifier for the source of the packet. + * + * dli_zdst is the zone identifier for the destination of the packet. + * + * A zone number of 0 is the global zone; a zone number of 0xffffffff + * means that the packet arrived from another host on the network, not + * from another zone on the same machine. + * + * An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates + * which of those it is. + */ +#define DLT_IPNET 226 + +/* + * CAN (Controller Area Network) frames, with a pseudo-header as supplied + * by Linux SocketCAN, and with multi-byte numerical fields in that header + * in big-endian byte order. + * + * See Documentation/networking/can.txt in the Linux source. + * + * Requested by Felix Obenhuber . + */ +#define DLT_CAN_SOCKETCAN 227 + +/* + * Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies + * whether it's v4 or v6. Requested by Darren Reed . + */ +#define DLT_IPV4 228 +#define DLT_IPV6 229 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing), and with no FCS at the end of the frame; requested by + * Jon Smirl . + */ +#define DLT_IEEE802_15_4_NOFCS 230 + +/* + * Raw D-Bus: + * + * http://www.freedesktop.org/wiki/Software/dbus + * + * messages: + * + * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages + * + * starting with the endianness flag, followed by the message type, etc., + * but without the authentication handshake before the message sequence: + * + * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol + * + * Requested by Martin Vidner . + */ +#define DLT_DBUS 231 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + */ +#define DLT_JUNIPER_VS 232 +#define DLT_JUNIPER_SRX_E2E 233 +#define DLT_JUNIPER_FIBRECHANNEL 234 + +/* + * DVB-CI (DVB Common Interface for communication between a PC Card + * module and a DVB receiver). See + * + * http://www.kaiser.cx/pcap-dvbci.html + * + * for the specification. + * + * Requested by Martin Kaiser . + */ +#define DLT_DVB_CI 235 + +/* + * Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but + * *not* the same as, 27.010). Requested by Hans-Christoph Schemmel + * . + */ +#define DLT_MUX27010 236 + +/* + * STANAG 5066 D_PDUs. Requested by M. Baris Demiray + * . + */ +#define DLT_STANAG_5066_D_PDU 237 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + */ +#define DLT_JUNIPER_ATM_CEMIC 238 + +/* + * NetFilter LOG messages + * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets) + * + * Requested by Jakub Zawadzki + */ +#define DLT_NFLOG 239 + +/* + * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type + * for Ethernet packets with a 4-byte pseudo-header and always + * with the payload including the FCS, as supplied by their + * netANALYZER hardware and software. + * + * Requested by Holger P. Frommer + */ +#define DLT_NETANALYZER 240 + +/* + * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type + * for Ethernet packets with a 4-byte pseudo-header and FCS and + * with the Ethernet header preceded by 7 bytes of preamble and + * 1 byte of SFD, as supplied by their netANALYZER hardware and + * software. + * + * Requested by Holger P. Frommer + */ +#define DLT_NETANALYZER_TRANSPARENT 241 + +/* + * IP-over-InfiniBand, as specified by RFC 4391. + * + * Requested by Petr Sumbera . + */ +#define DLT_IPOIB 242 + +/* + * MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0). + * + * Requested by Guy Martin . + */ +#define DLT_MPEG_2_TS 243 + +/* + * ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as + * used by their ng40 protocol tester. + * + * Requested by Jens Grimmer . + */ +#define DLT_NG40 244 + +/* + * Pseudo-header giving adapter number and flags, followed by an NFC + * (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU, + * as specified by NFC Forum Logical Link Control Protocol Technical + * Specification LLCP 1.1. + * + * Requested by Mike Wakerly . + */ +#define DLT_NFC_LLCP 245 + +/* + * 246 is used as LINKTYPE_PFSYNC; do not use it for any other purpose. + * + * DLT_PFSYNC has different values on different platforms, and all of + * them collide with something used elsewhere. On platforms that + * don't already define it, define it as 246. + */ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__APPLE__) +#define DLT_PFSYNC 246 +#endif + +/* + * Raw InfiniBand packets, starting with the Local Routing Header. + * + * Requested by Oren Kladnitsky . + */ +#define DLT_INFINIBAND 247 + +/* + * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6). + * + * Requested by Michael Tuexen . + */ +#define DLT_SCTP 248 + +/* + * USB packets, beginning with a USBPcap header. + * + * Requested by Tomasz Mon + */ +#define DLT_USBPCAP 249 + +/* + * Schweitzer Engineering Laboratories "RTAC" product serial-line + * packets. + * + * Requested by Chris Bontje . + */ +#define DLT_RTAC_SERIAL 250 + +/* + * Bluetooth Low Energy air interface link-layer packets. + * + * Requested by Mike Kershaw . + */ +#define DLT_BLUETOOTH_LE_LL 251 + +/* + * DLT type for upper-protocol layer PDU saves from wireshark. + * + * the actual contents are determined by two TAGs stored with each + * packet: + * EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the + * original packet. + * + * EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector + * that can make sense of the data stored. + */ +#define DLT_WIRESHARK_UPPER_PDU 252 + +/* + * DLT type for the netlink protocol (nlmon devices). + */ +#define DLT_NETLINK 253 + +/* + * Bluetooth Linux Monitor headers for the BlueZ stack. + */ +#define DLT_BLUETOOTH_LINUX_MONITOR 254 + +/* + * Bluetooth Basic Rate/Enhanced Data Rate baseband packets, as + * captured by Ubertooth. + */ +#define DLT_BLUETOOTH_BREDR_BB 255 + +/* + * Bluetooth Low Energy link layer packets, as captured by Ubertooth. + */ +#define DLT_BLUETOOTH_LE_LL_WITH_PHDR 256 + +/* + * PROFIBUS data link layer. + */ +#define DLT_PROFIBUS_DL 257 + +/* + * Apple's DLT_PKTAP headers. + * + * Sadly, the folks at Apple either had no clue that the DLT_USERn values + * are for internal use within an organization and partners only, and + * didn't know that the right way to get a link-layer header type is to + * ask tcpdump.org for one, or knew and didn't care, so they just + * used DLT_USER2, which causes problems for everything except for + * their version of tcpdump. + * + * So I'll just give them one; hopefully this will show up in a + * libpcap release in time for them to get this into 10.10 Big Sur + * or whatever Mavericks' successor is called. LINKTYPE_PKTAP + * will be 258 *even on macOS*; that is *intentional*, so that + * PKTAP files look the same on *all* OSes (different OSes can have + * different numerical values for a given DLT_, but *MUST NOT* have + * different values for what goes in a file, as files can be moved + * between OSes!). + * + * When capturing, on a system with a Darwin-based OS, on a device + * that returns 149 (DLT_USER2 and Apple's DLT_PKTAP) with this + * version of libpcap, the DLT_ value for the pcap_t will be DLT_PKTAP, + * and that will continue to be DLT_USER2 on Darwin-based OSes. That way, + * binary compatibility with Mavericks is preserved for programs using + * this version of libpcap. This does mean that if you were using + * DLT_USER2 for some capture device on macOS, you can't do so with + * this version of libpcap, just as you can't with Apple's libpcap - + * on macOS, they define DLT_PKTAP to be DLT_USER2, so programs won't + * be able to distinguish between PKTAP and whatever you were using + * DLT_USER2 for. + * + * If the program saves the capture to a file using this version of + * libpcap's pcap_dump code, the LINKTYPE_ value in the file will be + * LINKTYPE_PKTAP, which will be 258, even on Darwin-based OSes. + * That way, the file will *not* be a DLT_USER2 file. That means + * that the latest version of tcpdump, when built with this version + * of libpcap, and sufficiently recent versions of Wireshark will + * be able to read those files and interpret them correctly; however, + * Apple's version of tcpdump in OS X 10.9 won't be able to handle + * them. (Hopefully, Apple will pick up this version of libpcap, + * and the corresponding version of tcpdump, so that tcpdump will + * be able to handle the old LINKTYPE_USER2 captures *and* the new + * LINKTYPE_PKTAP captures.) + */ +#ifdef __APPLE__ +#define DLT_PKTAP DLT_USER2 +#else +#define DLT_PKTAP 258 +#endif + +/* + * Ethernet packets preceded by a header giving the last 6 octets + * of the preamble specified by 802.3-2012 Clause 65, section + * 65.1.3.2 "Transmit". + */ +#define DLT_EPON 259 + +/* + * IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" + * in the PICMG HPM.2 specification. + */ +#define DLT_IPMI_HPM_2 260 + +/* + * per Joshua Wright , formats for Zwave captures. + */ +#define DLT_ZWAVE_R1_R2 261 +#define DLT_ZWAVE_R3 262 + +/* + * per Steve Karg , formats for Wattstopper + * Digital Lighting Management room bus serial protocol captures. + */ +#define DLT_WATTSTOPPER_DLM 263 + +/* + * ISO 14443 contactless smart card messages. + */ +#define DLT_ISO_14443 264 + +/* + * Radio data system (RDS) groups. IEC 62106. + * Per Jonathan Brucker . + */ +#define DLT_RDS 265 + +/* + * USB packets, beginning with a Darwin (macOS, etc.) header. + */ +#define DLT_USB_DARWIN 266 + +/* + * OpenBSD DLT_OPENFLOW. + */ +#define DLT_OPENFLOW 267 + +/* + * SDLC frames containing SNA PDUs. + */ +#define DLT_SDLC 268 + +/* + * per "Selvig, Bjorn" used for + * TI protocol sniffer. + */ +#define DLT_TI_LLN_SNIFFER 269 + +/* + * per: Erik de Jong for + * https://github.com/eriknl/LoRaTap/releases/tag/v0.1 + */ +#define DLT_LORATAP 270 + +/* + * per: Stefanha at gmail.com for + * http://lists.sandelman.ca/pipermail/tcpdump-workers/2017-May/000772.html + * and: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/vsockmon.h + * for: http://qemu-project.org/Features/VirtioVsock + */ +#define DLT_VSOCK 271 + +/* + * Nordic Semiconductor Bluetooth LE sniffer. + */ +#define DLT_NORDIC_BLE 272 + +/* + * Excentis DOCSIS 3.1 RF sniffer (XRA-31) + * per: bruno.verstuyft at excentis.com + * http://www.xra31.com/xra-header + */ +#define DLT_DOCSIS31_XRA31 273 + +/* + * mPackets, as specified by IEEE 802.3br Figure 99-4, starting + * with the preamble and always ending with a CRC field. + */ +#define DLT_ETHERNET_MPACKET 274 + +/* + * DisplayPort AUX channel monitoring data as specified by VESA + * DisplayPort(DP) Standard preceeded by a pseudo-header. + * per dirk.eibach at gdsys.cc + */ +#define DLT_DISPLAYPORT_AUX 275 + +/* + * Linux cooked sockets v2. + */ +#define DLT_LINUX_SLL2 276 + +/* + * In case the code that includes this file (directly or indirectly) + * has also included OS files that happen to define DLT_MATCHING_MAX, + * with a different value (perhaps because that OS hasn't picked up + * the latest version of our DLT definitions), we undefine the + * previous value of DLT_MATCHING_MAX. + */ +#ifdef DLT_MATCHING_MAX +#undef DLT_MATCHING_MAX +#endif +#define DLT_MATCHING_MAX 276 /* highest value in the "matching" range */ + +/* + * DLT and savefile link type values are split into a class and + * a member of that class. A class value of 0 indicates a regular + * DLT_/LINKTYPE_ value. + */ +#define DLT_CLASS(x) ((x) & 0x03ff0000) + +/* + * NetBSD-specific generic "raw" link type. The class value indicates + * that this is the generic raw type, and the lower 16 bits are the + * address family we're dealing with. Those values are NetBSD-specific; + * do not assume that they correspond to AF_ values for your operating + * system. + */ +#define DLT_CLASS_NETBSD_RAWAF 0x02240000 +#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) +#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) +#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) + +#endif /* !_NET_DLT_H_ */ diff --git a/tools/compat/include/net/ethernet.h b/tools/compat/include/net/ethernet.h index 798ff9982..cc625a739 100644 --- a/tools/compat/include/net/ethernet.h +++ b/tools/compat/include/net/ethernet.h @@ -6,7 +6,7 @@ */ #ifndef _NET_ETHERNET_H_ -#define _NET_ETHERNET_H_ +#define _NET_ETHERNET_H_ /* * Some basic Ethernet constants. @@ -71,6 +71,14 @@ struct ether_addr { } __attribute__((__packed__)); #define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */ +#define ETHER_IS_IPV6_MULTICAST(addr) \ + (((addr)[0] == 0x33) && ((addr)[1] == 0x33)) +#define ETHER_IS_BROADCAST(addr) \ + (((addr)[0] & (addr)[1] & (addr)[2] & \ + (addr)[3] & (addr)[4] & (addr)[5]) == 0xff) +#define ETHER_IS_ZERO(addr) \ + (((addr)[0] | (addr)[1] | (addr)[2] | \ + (addr)[3] | (addr)[4] | (addr)[5]) == 0x00) /* * 802.1q Virtual LAN header. @@ -92,6 +100,11 @@ struct ether_vlan_header { ((((((pri) & 7) << 1) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK)) /* + * Ethernet protocol types. + * + * A public list is available from the IEEE Registration Authority: + * https://standards.ieee.org/products-services/regauth/ + * * NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields. * However, there are some conflicts. */ @@ -260,7 +273,7 @@ struct ether_vlan_header { #define ETHERTYPE_AARP 0x80F3 /* AppleTalk AARP */ /* 0x80F4 - 0x80F5 Kinetics */ #define ETHERTYPE_APOLLO 0x80F7 /* Apollo Computer */ -#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging (XXX conflicts) */ +#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging (XXX conflicts) */ /* 0x80FF - 0x8101 Wellfleet Communications (XXX conflicts) */ #define ETHERTYPE_BOFL 0x8102 /* Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.] */ #define ETHERTYPE_WELLFLEET 0x8103 /* Wellfleet Communications */ @@ -333,19 +346,32 @@ struct ether_vlan_header { #define ETHERTYPE_SLOW 0x8809 /* 802.3ad link aggregation (LACP) */ #define ETHERTYPE_PPP 0x880B /* PPP (obsolete by PPPoE) */ #define ETHERTYPE_HITACHI 0x8820 /* Hitachi Cable (Optoelectronic Systems Laboratory) */ -#define ETHERTYPE_TEST 0x8822 /* Network Conformance Testing */ +#define ETHERTYPE_TEST 0x8822 /* Network Conformance Testing */ #define ETHERTYPE_MPLS 0x8847 /* MPLS Unicast */ #define ETHERTYPE_MPLS_MCAST 0x8848 /* MPLS Multicast */ #define ETHERTYPE_AXIS 0x8856 /* Axis Communications AB proprietary bootstrap/config */ #define ETHERTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */ #define ETHERTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */ #define ETHERTYPE_LANPROBE 0x8888 /* HP LanProbe test? */ -#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ +#define ETHERTYPE_PAE 0x888E /* EAPOL PAE/802.1x */ +#define ETHERTYPE_PROFINET 0x8892 /* PROFINET RT Protocol */ +#define ETHERTYPE_AOE 0x88A2 /* ATA Protocol */ +#define ETHERTYPE_ETHERCAT 0x88A4 /* EtherCat Protocol */ +#define ETHERTYPE_QINQ 0x88A8 /* 802.1ad VLAN stacking */ +#define ETHERTYPE_POWERLINK 0x88AB /* Ethernet Powerlink (EPL) */ +#define ETHERTYPE_LLDP 0x88CC /* Link Layer Discovery Protocol */ +#define ETHERTYPE_SERCOS 0x88CD /* SERCOS III Protocol */ +#define ETHERTYPE_MACSEC 0x88E5 /* 802.1AE MAC Security */ +#define ETHERTYPE_PBB 0x88E7 /* 802.1Q Provider Backbone Bridges */ +#define ETHERTYPE_FCOE 0x8906 /* Fibre Channel over Ethernet */ #define ETHERTYPE_LOOPBACK 0x9000 /* Loopback: used to test interfaces */ +#define ETHERTYPE_8021Q9100 0x9100 /* IEEE 802.1Q stacking (proprietary) */ #define ETHERTYPE_LBACK ETHERTYPE_LOOPBACK /* DEC MOP loopback */ #define ETHERTYPE_XNSSM 0x9001 /* 3Com (Formerly Bridge Communications), XNS Systems Management */ #define ETHERTYPE_TCPSM 0x9002 /* 3Com (Formerly Bridge Communications), TCP/IP Systems Management */ #define ETHERTYPE_BCLOOP 0x9003 /* 3Com (Formerly Bridge Communications), loopback detection */ +#define ETHERTYPE_8021Q9200 0x9200 /* IEEE 802.1Q stacking (proprietary) */ +#define ETHERTYPE_8021Q9300 0x9300 /* IEEE 802.1Q stacking (proprietary) */ #define ETHERTYPE_DEBNI 0xAAAA /* DECNET? Used by VAX 6220 DEBNI */ #define ETHERTYPE_SONIX 0xFAF5 /* Sonix Arpeggio */ #define ETHERTYPE_VITAL 0xFF00 /* BBN VITAL-LanBridge cache wakeups */ @@ -371,7 +397,7 @@ struct ether_vlan_header { * ether_vlan_mtap. This function will re-insert VLAN tags for the duration * of the tap, so they show up properly for network analyzers. */ -#define ETHER_BPF_MTAP(_ifp, _m) do { \ +#define ETHER_BPF_MTAP(_ifp, _m) do { \ if (bpf_peers_present((_ifp)->if_bpf)) { \ M_ASSERTVALID(_m); \ if (((_m)->m_flags & M_VLANTAG) != 0) \ @@ -381,6 +407,66 @@ struct ether_vlan_header { } \ } while (0) +/* + * Names for 802.1q priorities ("802.1p"). Notice that in this scheme, + * (0 < 1), allowing default 0-tagged traffic to take priority over background + * tagged traffic. + */ +#define IEEE8021Q_PCP_BK 1 /* Background (lowest) */ +#define IEEE8021Q_PCP_BE 0 /* Best effort (default) */ +#define IEEE8021Q_PCP_EE 2 /* Excellent effort */ +#define IEEE8021Q_PCP_CA 3 /* Critical applications */ +#define IEEE8021Q_PCP_VI 4 /* Video, < 100ms latency */ +#define IEEE8021Q_PCP_VO 5 /* Video, < 10ms latency */ +#define IEEE8021Q_PCP_IC 6 /* Internetwork control */ +#define IEEE8021Q_PCP_NC 7 /* Network control (highest) */ + +#ifdef _KERNEL + +#include + +struct ifnet; +struct mbuf; +struct route; +struct sockaddr; +struct bpf_if; +struct ether_8021q_tag; + +extern uint32_t ether_crc32_le(const uint8_t *, size_t); +extern uint32_t ether_crc32_be(const uint8_t *, size_t); +extern void ether_demux(struct ifnet *, struct mbuf *); +extern void ether_ifattach(struct ifnet *, const u_int8_t *); +extern void ether_ifdetach(struct ifnet *); +extern int ether_ioctl(struct ifnet *, u_long, caddr_t); +extern int ether_output(struct ifnet *, struct mbuf *, + const struct sockaddr *, struct route *); +extern int ether_output_frame(struct ifnet *, struct mbuf *); +extern char *ether_sprintf(const u_int8_t *); +void ether_vlan_mtap(struct bpf_if *, struct mbuf *, + void *, u_int); +struct mbuf *ether_vlanencap_proto(struct mbuf *, uint16_t, uint16_t); +bool ether_8021q_frame(struct mbuf **mp, struct ifnet *ife, + struct ifnet *p, struct ether_8021q_tag *); +void ether_gen_addr(struct ifnet *ifp, struct ether_addr *hwaddr); + +static __inline struct mbuf *ether_vlanencap(struct mbuf *m, uint16_t tag) +{ + + return ether_vlanencap_proto(m, tag, ETHERTYPE_VLAN); +} + +/* new ethernet interface attached event */ +typedef void (*ether_ifattach_event_handler_t)(void *, struct ifnet *); +EVENTHANDLER_DECLARE(ether_ifattach_event, ether_ifattach_event_handler_t); + +#else /* _KERNEL */ + +#include + +/* + * Ethernet address conversion/parsing routines. + */ +__BEGIN_DECLS struct ether_addr *ether_aton(const char *); struct ether_addr *ether_aton_r(const char *, struct ether_addr *); int ether_hostton(const char *, struct ether_addr *); @@ -388,5 +474,8 @@ int ether_line(const char *, struct ether_addr *, char *); char *ether_ntoa(const struct ether_addr *); char *ether_ntoa_r(const struct ether_addr *, char *); int ether_ntohost(char *, const struct ether_addr *); +__END_DECLS + +#endif /* !_KERNEL */ #endif /* !_NET_ETHERNET_H_ */ diff --git a/tools/compat/include/net/flowtable.h b/tools/compat/include/net/flowtable.h deleted file mode 100644 index 5a1d92732..000000000 --- a/tools/compat/include/net/flowtable.h +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2014 Gleb Smirnoff - * Copyright (c) 2008-2010, BitGravity Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Neither the name of the BitGravity Corporation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -#ifndef _NET_FLOWTABLE_H_ -#define _NET_FLOWTABLE_H_ - -struct flowtable_stat { - uint64_t ft_collisions; - uint64_t ft_misses; - uint64_t ft_free_checks; - uint64_t ft_frees; - uint64_t ft_hits; - uint64_t ft_lookups; - uint64_t ft_fail_lle_invalid; - uint64_t ft_inserts; -}; - -#ifdef _KERNEL - -/* - * Given a flow table, look up the L3 and L2 information - * and return it in the route. - */ -int flowtable_lookup(sa_family_t, struct mbuf *, struct route *); -void flowtable_route_flush(sa_family_t, struct rtentry *); - -#endif /* _KERNEL */ -#endif /* !_NET_FLOWTABLE_H_ */ diff --git a/tools/compat/include/net/if.h b/tools/compat/include/net/if.h index df78fcbe9..ae179fa1f 100644 --- a/tools/compat/include/net/if.h +++ b/tools/compat/include/net/if.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -128,7 +130,7 @@ struct if_data { #define IFF_DEBUG 0x4 /* (n) turn on debugging */ #define IFF_LOOPBACK 0x8 /* (i) is a loopback net */ #define IFF_POINTOPOINT 0x10 /* (i) is a point-to-point link */ -/* 0x20 was IFF_SMART */ +#define IFF_KNOWSEPOCH 0x20 /* (i) calls if_input in net epoch */ #define IFF_DRV_RUNNING 0x40 /* (d) resources allocated */ #define IFF_NOARP 0x80 /* (n) no address resolution protocol */ #define IFF_PROMISC 0x100 /* (n) receive all packets */ @@ -146,6 +148,8 @@ struct if_data { #define IFF_STATICARP 0x80000 /* (n) static ARP */ #define IFF_DYING 0x200000 /* (n) interface is winding down */ #define IFF_RENAMING 0x400000 /* (n) interface is being renamed */ +#define IFF_NOGROUP 0x800000 /* (n) interface is not part of any groups */ + /* * Old names for driver flags so that user space tools can continue to use * the old (portable) names. @@ -159,7 +163,7 @@ struct if_data { #define IFF_CANTCHANGE \ (IFF_BROADCAST|IFF_POINTOPOINT|IFF_DRV_RUNNING|IFF_DRV_OACTIVE|\ IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_PROMISC|\ - IFF_DYING|IFF_CANTCONFIG) + IFF_DYING|IFF_CANTCONFIG|IFF_KNOWSEPOCH) /* * Values for if_link_state. @@ -191,7 +195,7 @@ struct if_data { * contains the enabled optional feature & capabilites that can be used * individually per packet and are specified in the mbuf pkthdr.csum_flags * field. IFCAP_* and CSUM_* do not match one to one and CSUM_* may be - * more detailed or differenciated than IFCAP_*. + * more detailed or differentiated than IFCAP_*. * Hwassist features are defined CSUM_* in sys/mbuf.h * * Capabilities that cannot be arbitrarily changed with ifconfig/ioctl @@ -218,13 +222,21 @@ struct if_data { #define IFCAP_TOE4 0x04000 /* interface can offload TCP */ #define IFCAP_TOE6 0x08000 /* interface can offload TCP6 */ #define IFCAP_VLAN_HWFILTER 0x10000 /* interface hw can filter vlan tag */ -#define IFCAP_POLLING_NOCOUNT 0x20000 /* polling ticks cannot be fragmented */ +/* available 0x20000 */ #define IFCAP_VLAN_HWTSO 0x40000 /* can do IFCAP_TSO on VLANs */ #define IFCAP_LINKSTATE 0x80000 /* the runtime link state is dynamic */ #define IFCAP_NETMAP 0x100000 /* netmap mode supported/enabled */ #define IFCAP_RXCSUM_IPV6 0x200000 /* can offload checksum on IPv6 RX */ #define IFCAP_TXCSUM_IPV6 0x400000 /* can offload checksum on IPv6 TX */ #define IFCAP_HWSTATS 0x800000 /* manages counters internally */ +#define IFCAP_TXRTLMT 0x1000000 /* hardware supports TX rate limiting */ +#define IFCAP_HWRXTSTMP 0x2000000 /* hardware rx timestamping */ +#define IFCAP_NOMAP 0x4000000 /* can TX unmapped mbufs */ +#define IFCAP_TXTLS4 0x8000000 /* can do TLS encryption and segmentation for TCP */ +#define IFCAP_TXTLS6 0x10000000 /* can do TLS encryption and segmentation for TCP6 */ +#define IFCAP_VXLAN_HWCSUM 0x20000000 /* can do IFCAN_HWCSUM on VXLANs */ +#define IFCAP_VXLAN_HWTSO 0x40000000 /* can do IFCAP_TSO on VXLANs */ +#define IFCAP_TXTLS_RTLMT 0x80000000 /* can do TLS with rate limiting */ #define IFCAP_HWCSUM_IPV6 (IFCAP_RXCSUM_IPV6 | IFCAP_TXCSUM_IPV6) @@ -232,6 +244,7 @@ struct if_data { #define IFCAP_TSO (IFCAP_TSO4 | IFCAP_TSO6) #define IFCAP_WOL (IFCAP_WOL_UCAST | IFCAP_WOL_MCAST | IFCAP_WOL_MAGIC) #define IFCAP_TOE (IFCAP_TOE4 | IFCAP_TOE6) +#define IFCAP_TXTLS (IFCAP_TXTLS4 | IFCAP_TXTLS6) #define IFCAP_CANTCHANGE (IFCAP_NETMAP) @@ -250,6 +263,7 @@ struct if_msghdr { int ifm_addrs; /* like rtm_addrs */ int ifm_flags; /* value of if_flags */ u_short ifm_index; /* index for associated ifp */ + u_short _ifm_spare1; struct if_data ifm_data;/* statistics and other data about if */ }; @@ -275,6 +289,7 @@ struct if_msghdrl { u_short _ifm_spare1; /* spare space to grow if_index, see if_var.h */ u_short ifm_len; /* length of if_msghdrl incl. if_data */ u_short ifm_data_off; /* offset of if_data from beginning */ + int _ifm_spare2; struct if_data ifm_data;/* statistics and other data about if */ }; @@ -290,6 +305,7 @@ struct ifa_msghdr { int ifam_addrs; /* like rtm_addrs */ int ifam_flags; /* value of ifa_flags */ u_short ifam_index; /* index for associated ifp */ + u_short _ifam_spare1; int ifam_metric; /* value of ifa_ifp->if_metric */ }; @@ -331,6 +347,7 @@ struct ifma_msghdr { int ifmam_addrs; /* like rtm_addrs */ int ifmam_flags; /* value of ifa_flags */ u_short ifmam_index; /* index for associated ifp */ + u_short _ifmam_spare1; }; /* @@ -362,7 +379,7 @@ struct ifreq_buffer { * definitions which begin with ifr_name. The * remainder may be interface specific. */ -struct ifreq { +struct ifreq { char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ union { struct sockaddr ifru_addr; @@ -384,7 +401,9 @@ struct ifreq { #define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ +#ifndef _KERNEL #define ifr_buffer ifr_ifru.ifru_buffer /* user supplied buffer with its length */ +#endif #define ifr_flags ifr_ifru.ifru_flags[0] /* flags (low 16 bits) */ #define ifr_flagshigh ifr_ifru.ifru_flags[1] /* flags (high 16 bits) */ #define ifr_jid ifr_ifru.ifru_jid /* jail/vnet */ @@ -392,12 +411,15 @@ struct ifreq { #define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ #define ifr_phys ifr_ifru.ifru_phys /* physical wire */ #define ifr_media ifr_ifru.ifru_media /* physical media */ +#ifndef _KERNEL #define ifr_data ifr_ifru.ifru_data /* for use by interface */ +#endif #define ifr_reqcap ifr_ifru.ifru_cap[0] /* requested capabilities */ #define ifr_curcap ifr_ifru.ifru_cap[1] /* current capabilities */ #define ifr_index ifr_ifru.ifru_index /* interface index */ #define ifr_fib ifr_ifru.ifru_fib /* interface fib */ #define ifr_vlan_pcp ifr_ifru.ifru_vlan_pcp /* VLAN priority */ +#define ifr_lan_pcp ifr_ifru.ifru_vlan_pcp /* VLAN priority */ }; #define _SIZEOF_ADDR_IFREQ(ifr) \ @@ -431,11 +453,11 @@ struct ifmediareq { int *ifm_ulist; /* media words */ }; -struct ifdrv { - char ifd_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - unsigned long ifd_cmd; - size_t ifd_len; - void *ifd_data; +struct ifdrv { + char ifd_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + unsigned long ifd_cmd; + size_t ifd_len; + void *ifd_data; }; /* @@ -457,7 +479,7 @@ struct ifstat { * for machine (useful for programs which * must know all networks accessible). */ -struct ifconf { +struct ifconf { int ifc_len; /* size of associated buffer */ union { caddr_t ifcu_buf; @@ -494,8 +516,10 @@ struct ifgroupreq { char ifgru_group[IFNAMSIZ]; struct ifg_req *ifgru_groups; } ifgr_ifgru; +#ifndef _KERNEL #define ifgr_group ifgr_ifgru.ifgru_group #define ifgr_groups ifgr_ifgru.ifgru_groups +#endif }; /* @@ -509,8 +533,66 @@ struct ifi2creq { uint8_t spare0; uint32_t spare1; uint8_t data[8]; /* read buffer */ +}; + +/* + * RSS hash. + */ + +#define RSS_FUNC_NONE 0 /* RSS disabled */ +#define RSS_FUNC_PRIVATE 1 /* non-standard */ +#define RSS_FUNC_TOEPLITZ 2 + +#define RSS_TYPE_IPV4 0x00000001 +#define RSS_TYPE_TCP_IPV4 0x00000002 +#define RSS_TYPE_IPV6 0x00000004 +#define RSS_TYPE_IPV6_EX 0x00000008 +#define RSS_TYPE_TCP_IPV6 0x00000010 +#define RSS_TYPE_TCP_IPV6_EX 0x00000020 +#define RSS_TYPE_UDP_IPV4 0x00000040 +#define RSS_TYPE_UDP_IPV6 0x00000080 +#define RSS_TYPE_UDP_IPV6_EX 0x00000100 + +#define RSS_KEYLEN 128 + +struct ifrsskey { + char ifrk_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + uint8_t ifrk_func; /* RSS_FUNC_ */ + uint8_t ifrk_spare0; + uint16_t ifrk_keylen; + uint8_t ifrk_key[RSS_KEYLEN]; }; +struct ifrsshash { + char ifrh_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + uint8_t ifrh_func; /* RSS_FUNC_ */ + uint8_t ifrh_spare0; + uint16_t ifrh_spare1; + uint32_t ifrh_types; /* RSS_TYPE_ */ +}; + +#define IFNET_PCP_NONE 0xff /* PCP disabled */ + +#define IFDR_MSG_SIZE 64 +#define IFDR_REASON_MSG 1 +#define IFDR_REASON_VENDOR 2 +struct ifdownreason { + char ifdr_name[IFNAMSIZ]; + uint32_t ifdr_reason; + uint32_t ifdr_vendor; + char ifdr_msg[IFDR_MSG_SIZE]; +}; + +#ifdef _KERNEL +#ifdef MALLOC_DECLARE +MALLOC_DECLARE(M_IFADDR); +MALLOC_DECLARE(M_IFMADDR); +#endif + +extern struct sx ifnet_detach_sxlock; + +#endif + struct if_nameindex { unsigned int if_index; /* 1, 2, ... */ char *if_name; /* null terminated name: "le0", ... */ diff --git a/tools/compat/include/net/if_arp.h b/tools/compat/include/net/if_arp.h index 455f9542d..f4c3bec21 100644 --- a/tools/compat/include/net/if_arp.h +++ b/tools/compat/include/net/if_arp.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -47,7 +49,6 @@ struct arphdr { u_short ar_hrd; /* format of hardware address */ #define ARPHRD_ETHER 1 /* ethernet hardware format */ #define ARPHRD_IEEE802 6 /* token-ring hardware format */ -#define ARPHRD_ARCNET 7 /* arcnet hardware format */ #define ARPHRD_FRELAY 15 /* frame relay hardware format */ #define ARPHRD_IEEE1394 24 /* firewire hardware format */ #define ARPHRD_INFINIBAND 32 /* infiniband hardware format */ @@ -104,8 +105,9 @@ struct arpstat { uint64_t rxrequests; /* # of ARP requests received by this host. */ uint64_t rxreplies; /* # of ARP replies received by this host. */ uint64_t received; /* # of ARP packets received by this host. */ + uint64_t txerrors; /* # of ARP requests failed to send. */ - uint64_t arp_spares[4]; /* For either the upper or lower half. */ + uint64_t arp_spares[3]; /* For either the upper or lower half. */ /* Abnormal event and error counting: */ uint64_t dropped; /* # of packets dropped waiting for a reply. */ uint64_t timeouts; /* # of times with entries removed */ @@ -113,4 +115,21 @@ struct arpstat { uint64_t dupips; /* # of duplicate IPs detected. */ }; +#ifdef _KERNEL +#include +#include + +VNET_PCPUSTAT_DECLARE(struct arpstat, arpstat); +/* + * In-kernel consumers can use these accessor macros directly to update + * stats. + */ +#define ARPSTAT_ADD(name, val) \ + VNET_PCPUSTAT_ADD(struct arpstat, arpstat, name, (val)) +#define ARPSTAT_SUB(name, val) ARPSTAT_ADD(name, -(val)) +#define ARPSTAT_INC(name) ARPSTAT_ADD(name, 1) +#define ARPSTAT_DEC(name) ARPSTAT_SUB(name, 1) + +#endif /* _KERNEL */ + #endif /* !_NET_IF_ARP_H_ */ diff --git a/tools/compat/include/net/if_bridgevar.h b/tools/compat/include/net/if_bridgevar.h index 3e550ebe7..3d13c45b2 100644 --- a/tools/compat/include/net/if_bridgevar.h +++ b/tools/compat/include/net/if_bridgevar.h @@ -1,6 +1,8 @@ /* $NetBSD: if_bridgevar.h,v 1.4 2003/07/08 07:13:50 itojun Exp $ */ /* + * SPDX-License-Identifier: BSD-4-Clause + * * Copyright 2001 Wasabi Systems, Inc. * All rights reserved. * @@ -74,6 +76,9 @@ * Data structure and control definitions for bridge interfaces. */ +#include +#include +//#include /* * Commands used in the SIOCSDRVSPEC ioctl. Note the lookup of the @@ -264,3 +269,52 @@ struct ifbpstpconf { #define ifbpstp_req ifbpstp_ifbpstpu.ifbpstpu_req }; +#define STP_STATES \ + "disabled", \ + "listening", \ + "learning", \ + "forwarding", \ + "blocking", \ + "discarding" + +#define STP_PROTOS \ + "stp", \ + "-", \ + "rstp" + +#define STP_ROLES \ + "disabled", \ + "root", \ + "designated", \ + "alternate", \ + "backup" + +#define PV2ID(pv, epri, eaddr) do { \ + epri = pv >> 48; \ + eaddr[0] = pv >> 40; \ + eaddr[1] = pv >> 32; \ + eaddr[2] = pv >> 24; \ + eaddr[3] = pv >> 16; \ + eaddr[4] = pv >> 8; \ + eaddr[5] = pv >> 0; \ +} while (0) + +#ifdef _KERNEL + +#define BRIDGE_INPUT(_ifp, _m) do { \ + KASSERT((_ifp)->if_bridge_input != NULL, \ + ("%s: if_bridge not loaded!", __func__)); \ + _m = (*(_ifp)->if_bridge_input)(_ifp, _m); \ + if (_m != NULL) \ + _ifp = _m->m_pkthdr.rcvif; \ +} while (0) + +#define BRIDGE_OUTPUT(_ifp, _m, _err) do { \ + KASSERT((_ifp)->if_bridge_output != NULL, \ + ("%s: if_bridge not loaded!", __func__)); \ + _err = (*(_ifp)->if_bridge_output)(_ifp, _m, NULL, NULL); \ +} while (0) + +extern void (*bridge_dn_p)(struct mbuf *, struct ifnet *); + +#endif /* _KERNEL */ diff --git a/tools/compat/include/net/if_dl.h b/tools/compat/include/net/if_dl.h index fb7bf1dba..d6f413be9 100644 --- a/tools/compat/include/net/if_dl.h +++ b/tools/compat/include/net/if_dl.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -75,7 +77,7 @@ struct sockaddr_dl *link_alloc_sdl(size_t, int); void link_free_sdl(struct sockaddr *sa); struct sockaddr_dl *link_init_sdl(struct ifnet *, struct sockaddr *, u_char); -void link_addr(const char *, struct sockaddr_dl *); -char *link_ntoa(const struct sockaddr_dl *); +void link_addr(const char *, struct sockaddr_dl *); +char *link_ntoa(const struct sockaddr_dl *); #endif diff --git a/tools/compat/include/net/if_gif.h b/tools/compat/include/net/if_gif.h index d3c23a1b9..2e61fcc16 100644 --- a/tools/compat/include/net/if_gif.h +++ b/tools/compat/include/net/if_gif.h @@ -2,7 +2,10 @@ /* $KAME: if_gif.h,v 1.17 2000/09/11 11:36:41 sumikawa Exp $ */ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * Copyright (c) 2018 Andrey V. Elsukov * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,6 +36,90 @@ #ifndef _NET_IF_GIF_H_ #define _NET_IF_GIF_H_ +#ifdef _KERNEL + +struct ip; +struct ip6_hdr; + +extern void (*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp, + int af); +extern void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m, + int af); +extern int (*ng_gif_output_p)(struct ifnet *ifp, struct mbuf **mp); +extern void (*ng_gif_attach_p)(struct ifnet *ifp); +extern void (*ng_gif_detach_p)(struct ifnet *ifp); + +struct gif_softc { + struct ifnet *gif_ifp; + int gif_family; + int gif_flags; + u_int gif_fibnum; + u_int gif_options; + void *gif_netgraph; /* netgraph node info */ + union { + void *hdr; + struct ip *iphdr; + struct ip6_hdr *ip6hdr; + } gif_uhdr; + + CK_LIST_ENTRY(gif_softc) chain; + CK_LIST_ENTRY(gif_softc) srchash; +}; +CK_LIST_HEAD(gif_list, gif_softc); +MALLOC_DECLARE(M_GIF); + +#ifndef GIF_HASH_SIZE +#define GIF_HASH_SIZE (1 << 4) +#endif + +#define GIF2IFP(sc) ((sc)->gif_ifp) +#define gif_iphdr gif_uhdr.iphdr +#define gif_hdr gif_uhdr.hdr +#define gif_ip6hdr gif_uhdr.ip6hdr + +#define GIF_MTU (1280) /* Default MTU */ +#define GIF_MTU_MIN (1280) /* Minimum MTU */ +#define GIF_MTU_MAX (8192) /* Maximum MTU */ + +struct etherip_header { +#if BYTE_ORDER == LITTLE_ENDIAN + u_int eip_resvl:4, /* reserved */ + eip_ver:4; /* version */ +#endif +#if BYTE_ORDER == BIG_ENDIAN + u_int eip_ver:4, /* version */ + eip_resvl:4; /* reserved */ +#endif + u_int8_t eip_resvh; /* reserved */ +} __packed; + +#define ETHERIP_VERSION 0x3 +/* mbuf adjust factor to force 32-bit alignment of IP header */ +#define ETHERIP_ALIGN 2 + +#define GIF_WAIT() epoch_wait_preempt(net_epoch_preempt) + +/* Prototypes */ +struct gif_list *gif_hashinit(void); +void gif_hashdestroy(struct gif_list *); + +void gif_input(struct mbuf *, struct ifnet *, int, uint8_t); +int gif_output(struct ifnet *, struct mbuf *, const struct sockaddr *, + struct route *); + +void in_gif_init(void); +void in_gif_uninit(void); +int in_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); +int in_gif_ioctl(struct gif_softc *, u_long, caddr_t); +int in_gif_setopts(struct gif_softc *, u_int); + +void in6_gif_init(void); +void in6_gif_uninit(void); +int in6_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); +int in6_gif_ioctl(struct gif_softc *, u_long, caddr_t); +int in6_gif_setopts(struct gif_softc *, u_int); +#endif /* _KERNEL */ + #define GIFGOPTS _IOWR('i', 150, struct ifreq) #define GIFSOPTS _IOW('i', 151, struct ifreq) diff --git a/tools/compat/include/net/if_gre.h b/tools/compat/include/net/if_gre.h index ef66edd0e..de3c59793 100644 --- a/tools/compat/include/net/if_gre.h +++ b/tools/compat/include/net/if_gre.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 1998 The NetBSD Foundation, Inc. * Copyright (c) 2014 Andrey V. Elsukov * All rights reserved @@ -34,6 +36,130 @@ #ifndef _NET_IF_GRE_H_ #define _NET_IF_GRE_H_ +#ifdef _KERNEL +/* GRE header according to RFC 2784 and RFC 2890 */ +struct grehdr { + uint16_t gre_flags; /* GRE flags */ +#define GRE_FLAGS_CP 0x8000 /* checksum present */ +#define GRE_FLAGS_KP 0x2000 /* key present */ +#define GRE_FLAGS_SP 0x1000 /* sequence present */ +#define GRE_FLAGS_MASK (GRE_FLAGS_CP|GRE_FLAGS_KP|GRE_FLAGS_SP) + uint16_t gre_proto; /* protocol type */ + uint32_t gre_opts[0]; /* optional fields */ +} __packed; + +#ifdef INET +struct greip { + struct ip gi_ip; + struct grehdr gi_gre; +} __packed; + +struct greudp { + struct ip gi_ip; + struct udphdr gi_udp; + struct grehdr gi_gre; +} __packed; +#endif /* INET */ + +#ifdef INET6 +struct greip6 { + struct ip6_hdr gi6_ip6; + struct grehdr gi6_gre; +} __packed; + +struct greudp6 { + struct ip6_hdr gi6_ip6; + struct udphdr gi6_udp; + struct grehdr gi6_gre; +} __packed; +#endif /* INET6 */ + +CK_LIST_HEAD(gre_list, gre_softc); +CK_LIST_HEAD(gre_sockets, gre_socket); +struct gre_socket { + struct socket *so; + struct gre_list list; + CK_LIST_ENTRY(gre_socket) chain; + struct epoch_context epoch_ctx; +}; + +struct gre_softc { + struct ifnet *gre_ifp; + int gre_family; /* AF of delivery header */ + uint32_t gre_iseq; + uint32_t gre_oseq; + uint32_t gre_key; + uint32_t gre_options; + uint32_t gre_csumflags; + uint32_t gre_port; + u_int gre_fibnum; + u_int gre_hlen; /* header size */ + union { + void *hdr; +#ifdef INET + struct greip *iphdr; + struct greudp *udphdr; +#endif +#ifdef INET6 + struct greip6 *ip6hdr; + struct greudp6 *udp6hdr; +#endif + } gre_uhdr; + struct gre_socket *gre_so; + + CK_LIST_ENTRY(gre_softc) chain; + CK_LIST_ENTRY(gre_softc) srchash; +}; +MALLOC_DECLARE(M_GRE); + +#ifndef GRE_HASH_SIZE +#define GRE_HASH_SIZE (1 << 4) +#endif + +#define GRE2IFP(sc) ((sc)->gre_ifp) +#define GRE_RLOCK_TRACKER struct epoch_tracker gre_et +#define GRE_RLOCK() epoch_enter_preempt(net_epoch_preempt, &gre_et) +#define GRE_RUNLOCK() epoch_exit_preempt(net_epoch_preempt, &gre_et) +#define GRE_WAIT() epoch_wait_preempt(net_epoch_preempt) + +#define gre_hdr gre_uhdr.hdr +#define gre_iphdr gre_uhdr.iphdr +#define gre_ip6hdr gre_uhdr.ip6hdr +#define gre_udphdr gre_uhdr.udphdr +#define gre_udp6hdr gre_uhdr.udp6hdr + +#define gre_oip gre_iphdr->gi_ip +#define gre_udp gre_udphdr->gi_udp +#define gre_oip6 gre_ip6hdr->gi6_ip6 +#define gre_udp6 gre_udp6hdr->gi6_udp + +struct gre_list *gre_hashinit(void); +void gre_hashdestroy(struct gre_list *); + +int gre_input(struct mbuf *, int, int, void *); +void gre_update_hdr(struct gre_softc *, struct grehdr *); +void gre_update_udphdr(struct gre_softc *, struct udphdr *, uint16_t); +void gre_sofree(epoch_context_t); + +void in_gre_init(void); +void in_gre_uninit(void); +int in_gre_setopts(struct gre_softc *, u_long, uint32_t); +int in_gre_ioctl(struct gre_softc *, u_long, caddr_t); +int in_gre_output(struct mbuf *, int, int); + +void in6_gre_init(void); +void in6_gre_uninit(void); +int in6_gre_setopts(struct gre_softc *, u_long, uint32_t); +int in6_gre_ioctl(struct gre_softc *, u_long, caddr_t); +int in6_gre_output(struct mbuf *, int, int, uint32_t); +/* + * CISCO uses special type for GRE tunnel created as part of WCCP + * connection, while in fact those packets are just IPv4 encapsulated + * into GRE. + */ +#define ETHERTYPE_WCCP 0x883E +#endif /* _KERNEL */ + #define GRESADDRS _IOW('i', 101, struct ifreq) #define GRESADDRD _IOW('i', 102, struct ifreq) #define GREGADDRS _IOWR('i', 103, struct ifreq) @@ -45,9 +171,15 @@ #define GRESKEY _IOW('i', 108, struct ifreq) #define GREGOPTS _IOWR('i', 109, struct ifreq) #define GRESOPTS _IOW('i', 110, struct ifreq) +#define GREGPORT _IOWR('i', 111, struct ifreq) +#define GRESPORT _IOW('i', 112, struct ifreq) + +/* GRE-in-UDP encapsulation destination port as defined in RFC8086 */ +#define GRE_UDPPORT 4754 #define GRE_ENABLE_CSUM 0x0001 #define GRE_ENABLE_SEQ 0x0002 -#define GRE_OPTMASK (GRE_ENABLE_CSUM|GRE_ENABLE_SEQ) +#define GRE_UDPENCAP 0x0004 +#define GRE_OPTMASK (GRE_ENABLE_CSUM|GRE_ENABLE_SEQ|GRE_UDPENCAP) #endif /* _NET_IF_GRE_H_ */ diff --git a/tools/compat/include/net/if_pfsync.h b/tools/compat/include/net/if_pfsync.h index 980deefa5..f26a2ae34 100644 --- a/tools/compat/include/net/if_pfsync.h +++ b/tools/compat/include/net/if_pfsync.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2001 Michael Shalayeff * All rights reserved. * @@ -45,7 +47,6 @@ * $FreeBSD$ */ - #ifndef _NET_IF_PFSYNC_H_ #define _NET_IF_PFSYNC_H_ @@ -241,4 +242,25 @@ struct pfsyncreq { #define SIOCSETPFSYNC _IOW('i', 247, struct ifreq) #define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq) +#ifdef _KERNEL + +/* + * this shows where a pf state is with respect to the syncing. + */ +#define PFSYNC_S_INS 0x00 +#define PFSYNC_S_IACK 0x01 +#define PFSYNC_S_UPD 0x02 +#define PFSYNC_S_UPD_C 0x03 +#define PFSYNC_S_DEL 0x04 +#define PFSYNC_S_COUNT 0x05 + +#define PFSYNC_S_DEFER 0xfe +#define PFSYNC_S_NONE 0xff + +#define PFSYNC_SI_IOCTL 0x01 +#define PFSYNC_SI_CKSUM 0x02 +#define PFSYNC_SI_ACK 0x04 + +#endif /* _KERNEL */ + #endif /* _NET_IF_PFSYNC_H_ */ diff --git a/tools/compat/include/net/if_types.h b/tools/compat/include/net/if_types.h index 92e101ac6..1103d5f90 100644 --- a/tools/compat/include/net/if_types.h +++ b/tools/compat/include/net/if_types.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -113,7 +115,7 @@ typedef enum { IFT_QLLC = 0x44, /* SNA QLLC */ IFT_FASTETHERFX = 0x45, /* Fast Ethernet (100BaseFX) */ IFT_CHANNEL = 0x46, /* channel */ - IFT_IEEE80211 = 0x47, /* radio spread spectrum */ + IFT_IEEE80211 = 0x47, /* radio spread spectrum (unused) */ IFT_IBM370PARCHAN = 0x48, /* IBM System 360/370 OEMI Channel */ IFT_ESCON = 0x49, /* IBM Enterprise Systems Connection */ IFT_DLSW = 0x4a, /* Data Link Switching */ @@ -240,6 +242,7 @@ typedef enum { IFT_OPTICALCHANNEL = 0xc3, /* Optical Channel */ IFT_OPTICALTRANSPORT = 0xc4, /* Optical Transport */ IFT_INFINIBAND = 0xc7, /* Infiniband */ + IFT_INFINIBANDLAG = 0xc8, /* Infiniband Link Aggregate */ IFT_BRIDGE = 0xd1, /* Transparent bridge interface */ IFT_STF = 0xd7, /* 6to4 interface */ diff --git a/tools/compat/include/net/if_vlan_var.h b/tools/compat/include/net/if_vlan_var.h index add69a3e8..1b9540f18 100644 --- a/tools/compat/include/net/if_vlan_var.h +++ b/tools/compat/include/net/if_vlan_var.h @@ -69,26 +69,105 @@ struct vlanreq { char vlr_parent[IFNAMSIZ]; u_short vlr_tag; + u_short vlr_proto; }; #define SIOCSETVLAN SIOCSIFGENERIC #define SIOCGETVLAN SIOCGIFGENERIC -#define SIOCGVLANPCP _IOWR('i', 152, struct ifreq) /* Get VLAN PCP */ -#define SIOCSVLANPCP _IOW('i', 153, struct ifreq) /* Set VLAN PCP */ +#define SIOCGVLANPCP SIOCGLANPCP /* Get VLAN PCP */ +#define SIOCSVLANPCP SIOCSLANPCP /* Set VLAN PCP */ + +#ifdef _KERNEL +/* + * Drivers that are capable of adding and removing the VLAN header + * in hardware indicate they support this by marking IFCAP_VLAN_HWTAGGING + * in if_capabilities. Drivers for hardware that is capable + * of handling larger MTU's that may include a software-appended + * VLAN header w/o lowering the normal MTU should mark IFCAP_VLAN_MTU + * in if_capabilities; this notifies the VLAN code it can leave the + * MTU on the vlan interface at the normal setting. + */ /* - * Names for 802.1q priorities ("802.1p"). Notice that in this scheme, - * (0 < 1), allowing default 0-tagged traffic to take priority over background - * tagged traffic. + * VLAN tags are stored in host byte order. Byte swapping may be + * necessary. + * + * Drivers that support hardware VLAN tag stripping fill in the + * received VLAN tag (containing both vlan and priority information) + * into the ether_vtag mbuf packet header field: + * + * m->m_pkthdr.ether_vtag = vtag; // ntohs()? + * m->m_flags |= M_VLANTAG; + * + * to mark the packet m with the specified VLAN tag. + * + * On output the driver should check the mbuf for the M_VLANTAG + * flag to see if a VLAN tag is present and valid: + * + * if (m->m_flags & M_VLANTAG) { + * ... = m->m_pkthdr.ether_vtag; // htons()? + * ... pass tag to hardware ... + * } + * + * Note that a driver must indicate it supports hardware VLAN + * stripping/insertion by marking IFCAP_VLAN_HWTAGGING in + * if_capabilities. */ -#define IEEE8021Q_PCP_BK 1 /* Background (lowest) */ -#define IEEE8021Q_PCP_BE 0 /* Best effort (default) */ -#define IEEE8021Q_PCP_EE 2 /* Excellent effort */ -#define IEEE8021Q_PCP_CA 3 /* Critical applications */ -#define IEEE8021Q_PCP_VI 4 /* Video, < 100ms latency */ -#define IEEE8021Q_PCP_VO 5 /* Video, < 10ms latency */ -#define IEEE8021Q_PCP_IC 6 /* Internetwork control */ -#define IEEE8021Q_PCP_NC 7 /* Network control (highest) */ +/* + * The 802.1q code may also tag mbufs with the PCP (priority) field for use in + * other layers of the stack, in which case an m_tag will be used. This is + * semantically quite different from use of the ether_vtag field, which is + * defined only between the device driver and VLAN layer. + */ +#define MTAG_8021Q 1326104895 +#define MTAG_8021Q_PCP_IN 0 /* Input priority. */ +#define MTAG_8021Q_PCP_OUT 1 /* Output priority. */ + +/* + * 802.1q full tag. Proto and vid are stored in host byte order. + */ +struct ether_8021q_tag { + uint16_t proto; + uint16_t vid; + uint8_t pcp; +}; + +#define VLAN_CAPABILITIES(_ifp) do { \ + if ((_ifp)->if_vlantrunk != NULL) \ + (*vlan_trunk_cap_p)(_ifp); \ +} while (0) + +#define VLAN_TRUNKDEV(_ifp) \ + ((_ifp)->if_type == IFT_L2VLAN ? (*vlan_trunkdev_p)((_ifp)) : NULL) +#define VLAN_TAG(_ifp, _vid) \ + ((_ifp)->if_type == IFT_L2VLAN ? (*vlan_tag_p)((_ifp), (_vid)) : EINVAL) +#define VLAN_PCP(_ifp, _pcp) \ + ((_ifp)->if_type == IFT_L2VLAN ? (*vlan_pcp_p)((_ifp), (_pcp)) : EINVAL) +#define VLAN_COOKIE(_ifp) \ + ((_ifp)->if_type == IFT_L2VLAN ? (*vlan_cookie_p)((_ifp)) : NULL) +#define VLAN_SETCOOKIE(_ifp, _cookie) \ + ((_ifp)->if_type == IFT_L2VLAN ? \ + (*vlan_setcookie_p)((_ifp), (_cookie)) : EINVAL) +#define VLAN_DEVAT(_ifp, _vid) \ + ((_ifp)->if_vlantrunk != NULL ? (*vlan_devat_p)((_ifp), (_vid)) : NULL) + +extern void (*vlan_trunk_cap_p)(struct ifnet *); +extern struct ifnet *(*vlan_trunkdev_p)(struct ifnet *); +extern struct ifnet *(*vlan_devat_p)(struct ifnet *, uint16_t); +extern int (*vlan_tag_p)(struct ifnet *, uint16_t *); +extern int (*vlan_pcp_p)(struct ifnet *, uint16_t *); +extern int (*vlan_setcookie_p)(struct ifnet *, void *); +extern void *(*vlan_cookie_p)(struct ifnet *); + +#include + +/* VLAN state change events */ +typedef void (*vlan_config_fn)(void *, struct ifnet *, uint16_t); +typedef void (*vlan_unconfig_fn)(void *, struct ifnet *, uint16_t); +EVENTHANDLER_DECLARE(vlan_config, vlan_config_fn); +EVENTHANDLER_DECLARE(vlan_unconfig, vlan_unconfig_fn); + +#endif /* _KERNEL */ #endif /* _NET_IF_VLAN_VAR_H_ */ diff --git a/tools/compat/include/net/if_vxlan.h b/tools/compat/include/net/if_vxlan.h index 557b4e7b5..01c73a930 100644 --- a/tools/compat/include/net/if_vxlan.h +++ b/tools/compat/include/net/if_vxlan.h @@ -54,6 +54,12 @@ struct vxlan_header { #define VXLAN_PORT 4789 #define VXLAN_LEGACY_PORT 8472 +union vxlan_sockaddr { + struct sockaddr sa; + struct sockaddr_in in4; + struct sockaddr_in6 in6; +}; + struct ifvxlanparam { uint64_t vxlp_with; @@ -72,10 +78,8 @@ struct ifvxlanparam { #define VXLAN_PARAM_WITH_LEARN 0x1000 uint32_t vxlp_vni; - struct in_addr vxlp_local_in4; - struct in6_addr vxlp_local_in6; - struct in_addr vxlp_remote_in4; - struct in6_addr vxlp_remote_in6; + union vxlan_sockaddr vxlp_local_sa; + union vxlan_sockaddr vxlp_remote_sa; uint16_t vxlp_local_port; uint16_t vxlp_remote_port; uint16_t vxlp_min_port; @@ -87,12 +91,6 @@ struct ifvxlanparam { uint8_t vxlp_learn; }; -union vxlan_sockaddr { - struct sockaddr sa; - struct sockaddr_in in4; - struct sockaddr_in6 in6; -}; - #define VXLAN_SOCKADDR_IS_IPV4(_vxsin) ((_vxsin)->sa.sa_family == AF_INET) #define VXLAN_SOCKADDR_IS_IPV6(_vxsin) ((_vxsin)->sa.sa_family == AF_INET6) #define VXLAN_SOCKADDR_IS_IPV46(_vxsin) \ @@ -145,4 +143,11 @@ struct ifvxlancmd { char vxlcmd_ifname[IFNAMSIZ]; }; +#ifdef _KERNEL +typedef void (*vxlan_event_handler_t)(void *, struct ifnet *, sa_family_t, + u_int); +EVENTHANDLER_DECLARE(vxlan_start, vxlan_event_handler_t); +EVENTHANDLER_DECLARE(vxlan_stop, vxlan_event_handler_t); +#endif + #endif /* _NET_IF_VXLAN_H_ */ diff --git a/tools/compat/include/net/iso88025.h b/tools/compat/include/net/iso88025.h deleted file mode 100644 index 459eb3da2..000000000 --- a/tools/compat/include/net/iso88025.h +++ /dev/null @@ -1,180 +0,0 @@ -/*- - * Copyright (c) 1998, Larry Lile - * All rights reserved. - * - * For latest sources and information on this driver, please - * go to http://anarchy.stdio.com. - * - * Questions, comments or suggestions should be directed to - * Larry Lile . - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - * Information gathered from tokenring@freebsd, /sys/net/ethernet.h and - * the Mach token ring driver. - */ - -/* - * Fundamental constants relating to iso 802.5 - */ - -#ifndef _NET_ISO88025_H_ -#define _NET_ISO88025_H_ - -#ifdef FSTACK -#ifndef __packed -#define __packed __attribute__((__packed__)) -#endif -#endif - -/* - * General ISO 802.5 definitions - */ -#define ISO88025_ADDR_LEN 6 -#define ISO88025_CF_LEN 2 -#define ISO88025_HDR_LEN (ISO88025_CF_LEN + (ISO88025_ADDR_LEN * 2)) -#define RCF_LEN 2 -#define RIF_MAX_RD 14 -#define RIF_MAX_LEN 16 - -#define TR_AC 0x10 -#define TR_LLC_FRAME 0x40 - -#define TR_4MBPS 4000000 -#define TR_16MBPS 16000000 -#define TR_100MBPS 100000000 - -/* - * Source routing - */ -#define TR_RII 0x80 -#define TR_RCF_BCST_MASK 0xe000 -#define TR_RCF_LEN_MASK 0x1f00 -#define TR_RCF_DIR 0x0080 -#define TR_RCF_LF_MASK 0x0070 - -#define TR_RCF_RIFLEN(x) ((ntohs(x) & TR_RCF_LEN_MASK) >> 8) - -/* - * Minimum and maximum packet payload lengths. - */ -#define ISO88025_MIN_LEN 0 -#define ISO88025_MAX_LEN_4 4464 -#define ISO88025_MAX_LEN_16 17960 -#define ISO88025_MAX_LEN ISO88025_MAX_LEN_16 - -/* - * A macro to validate a length with - */ -#define ISO88025_IS_VALID_LEN(foo) \ - ((foo) >= ISO88025_MIN_LEN && (foo) <= ISO88025_MAX_LEN) - -/* Access Control field */ -#define AC_PRI_MASK 0xe0 /* Priority bits */ -#define AC_TOKEN 0x10 /* Token bit: 0=Token, 1=Frame */ -#define AC_MONITOR 0x08 /* Monitor */ -#define AC_RESV_MASK 0x07 /* Reservation bits */ - -/* Frame Control field */ -#define FC_FT_MASK 0xc0 /* Frame Type */ -#define FC_FT_MAC 0x00 /* MAC frame */ -#define FC_FT_LLC 0x40 /* LLC frame */ -#define FC_ATTN_MASK 0x0f /* Attention bits */ -#define FC_ATTN_EB 0x01 /* Express buffer */ -#define FC_ATTN_BE 0x02 /* Beacon */ -#define FC_ATTN_CT 0x03 /* Claim token */ -#define FC_ATTN_RP 0x04 /* Ring purge */ -#define FC_ATTN_AMP 0x05 /* Active monitor present */ -#define FC_ATTN_SMP 0x06 /* Standby monitor present */ - -/* Token Ring destination address */ -#define DA_IG 0x80 /* Individual/group address. */ - /* 0=Individual, 1=Group */ -#define DA_UL 0x40 /* Universal/local address. */ - /* 0=Universal, 1=Local */ -/* Token Ring source address */ -#define SA_RII 0x80 /* Routing information indicator */ -#define SA_IG 0x40 /* Individual/group address */ - /* 0=Group, 1=Individual */ - -/* - * ISO 802.5 physical header - */ -struct iso88025_header { - u_int8_t ac; /* access control field */ - u_int8_t fc; /* frame control field */ - u_int8_t iso88025_dhost[ISO88025_ADDR_LEN]; /* destination address */ - u_int8_t iso88025_shost[ISO88025_ADDR_LEN]; /* source address */ - u_int16_t rcf; /* route control field */ - u_int16_t rd[RIF_MAX_RD]; /* routing designators */ -} __packed; - -struct iso88025_rif { - u_int16_t rcf; /* route control field */ - u_int16_t rd[RIF_MAX_RD]; /* routing designators */ -} __packed; - -struct iso88025_sockaddr_data { - u_char ether_dhost[ISO88025_ADDR_LEN]; - u_char ether_shost[ISO88025_ADDR_LEN]; - u_char ac; - u_char fc; -}; - -struct iso88025_sockaddr_dl_data { - u_short trld_rcf; - u_short *trld_route[RIF_MAX_LEN]; -}; - -#define ISO88025_MAX(a, b) (((a)>(b))?(a):(b)) -#define SDL_ISO88025(s) ((struct iso88025_sockaddr_dl_data *) \ - ((s)->sdl_data + \ - ISO88025_MAX((s)->sdl_nlen + (s)->sdl_alen + \ - (s)->sdl_slen, 12))) - -/* - * Structure of a 48-bit iso 802.5 address. - * ( We could also add the 16 bit addresses as a union) - */ -struct iso88025_addr { - u_char octet[ISO88025_ADDR_LEN]; -}; - -#define ISO88025_MAX_MTU 18000 -#define ISO88025_DEFAULT_MTU 1500 - -#define ISO88025_BPF_UNSUPPORTED 0 -#define ISO88025_BPF_SUPPORTED 1 - -#ifdef _KERNEL -void iso88025_ifattach (struct ifnet *, const u_int8_t *, int); -void iso88025_ifdetach (struct ifnet *, int); -int iso88025_ioctl (struct ifnet *, u_long, caddr_t ); -int iso88025_output (struct ifnet *, struct mbuf *, - const struct sockaddr *, struct route *); -void iso88025_input (struct ifnet *, struct mbuf *); -#endif /* _KERNEL */ - -#endif /* !_NET_ISO88025_H_ */ diff --git a/tools/compat/include/net/netisr.h b/tools/compat/include/net/netisr.h index 63764a74f..32d2aa838 100644 --- a/tools/compat/include/net/netisr.h +++ b/tools/compat/include/net/netisr.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2007-2009 Robert N. M. Watson * Copyright (c) 2010-2011 Juniper Networks, Inc. * All rights reserved. @@ -55,7 +57,6 @@ #define NETISR_ARP 4 /* same as AF_LINK */ #define NETISR_ETHER 5 /* ethernet input */ #define NETISR_IPV6 6 -#define NETISR_NATM 7 #define NETISR_EPAIR 8 /* if_epair(4) */ #define NETISR_IP_DIRECT 9 /* direct-dispatch IPv4 */ #define NETISR_IPV6_DIRECT 10 /* direct-dispatch IPv6 */ diff --git a/tools/compat/include/net/netisr_internal.h b/tools/compat/include/net/netisr_internal.h index e5fbb12cc..e55e609db 100644 --- a/tools/compat/include/net/netisr_internal.h +++ b/tools/compat/include/net/netisr_internal.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2007-2009 Robert N. M. Watson * Copyright (c) 2010-2011 Juniper Networks, Inc. * All rights reserved. diff --git a/tools/compat/include/net/pfvar.h b/tools/compat/include/net/pfvar.h index c7b931db7..c97912970 100644 --- a/tools/compat/include/net/pfvar.h +++ b/tools/compat/include/net/pfvar.h @@ -1,4 +1,6 @@ -/* +/*- + * SPDX-License-Identifier: BSD-2-Clause + * * Copyright (c) 2001 Daniel Hartmeier * All rights reserved. * @@ -47,46 +49,6 @@ #define __packed __attribute__((__packed__)) #endif -struct pf_addr { - union { - struct in_addr v4; - struct in6_addr v6; - u_int8_t addr8[16]; - u_int16_t addr16[8]; - u_int32_t addr32[4]; - } pfa; /* 128-bit address */ -#define v4 pfa.v4 -#define v6 pfa.v6 -#define addr8 pfa.addr8 -#define addr16 pfa.addr16 -#define addr32 pfa.addr32 -}; - -#define PFI_AFLAG_NETWORK 0x01 -#define PFI_AFLAG_BROADCAST 0x02 -#define PFI_AFLAG_PEER 0x04 -#define PFI_AFLAG_MODEMASK 0x07 -#define PFI_AFLAG_NOALIAS 0x08 - -struct pf_addr_wrap { - union { - struct { - struct pf_addr addr; - struct pf_addr mask; - } a; - char ifname[IFNAMSIZ]; - char tblname[PF_TABLE_NAME_SIZE]; - } v; - union { - struct pfi_dynaddr *dyn; - struct pfr_ktable *tbl; - int dyncnt; - int tblcnt; - } p; - u_int8_t type; /* PF_ADDR_* */ - u_int8_t iflags; /* PFI_AFLAG_* */ -}; - /* Both IPv4 and IPv6 */ #ifdef PF_INET_INET6 @@ -216,47 +178,22 @@ struct pf_addr_wrap { (neg) \ ) +#define PF_ALGNMNT(off) (((off) % 2) == 0) -struct pf_rule_uid { - uid_t uid[2]; - u_int8_t op; -}; +#ifdef _KERNEL -struct pf_rule_gid { - uid_t gid[2]; - u_int8_t op; -}; - -struct pf_rule_addr { - struct pf_addr_wrap addr; - u_int16_t port[2]; - u_int8_t neg; - u_int8_t port_op; -}; - -struct pf_pooladdr { +struct pf_kpooladdr { struct pf_addr_wrap addr; - TAILQ_ENTRY(pf_pooladdr) entries; + TAILQ_ENTRY(pf_kpooladdr) entries; char ifname[IFNAMSIZ]; - struct pfi_kif *kif; + struct pfi_kkif *kif; }; -TAILQ_HEAD(pf_palist, pf_pooladdr); +TAILQ_HEAD(pf_kpalist, pf_kpooladdr); -struct pf_poolhashkey { - union { - u_int8_t key8[16]; - u_int16_t key16[8]; - u_int32_t key32[4]; - } pfk; /* 128-bit hash key */ -#define key8 pfk.key8 -#define key16 pfk.key16 -#define key32 pfk.key32 -}; - -struct pf_pool { - struct pf_palist list; - struct pf_pooladdr *cur; +struct pf_kpool { + struct pf_kpalist list; + struct pf_kpooladdr *cur; struct pf_poolhashkey key; struct pf_addr counter; int tblidx; @@ -264,149 +201,33 @@ struct pf_pool { u_int8_t opts; }; - -/* A packed Operating System description for fingerprinting */ -typedef u_int32_t pf_osfp_t; -#define PF_OSFP_ANY ((pf_osfp_t)0) -#define PF_OSFP_UNKNOWN ((pf_osfp_t)-1) -#define PF_OSFP_NOMATCH ((pf_osfp_t)-2) - -struct pf_osfp_entry { - SLIST_ENTRY(pf_osfp_entry) fp_entry; - pf_osfp_t fp_os; - int fp_enflags; -#define PF_OSFP_EXPANDED 0x001 /* expanded entry */ -#define PF_OSFP_GENERIC 0x002 /* generic signature */ -#define PF_OSFP_NODETAIL 0x004 /* no p0f details */ -#define PF_OSFP_LEN 32 - char fp_class_nm[PF_OSFP_LEN]; - char fp_version_nm[PF_OSFP_LEN]; - char fp_subtype_nm[PF_OSFP_LEN]; -}; -#define PF_OSFP_ENTRY_EQ(a, b) \ - ((a)->fp_os == (b)->fp_os && \ - memcmp((a)->fp_class_nm, (b)->fp_class_nm, PF_OSFP_LEN) == 0 && \ - memcmp((a)->fp_version_nm, (b)->fp_version_nm, PF_OSFP_LEN) == 0 && \ - memcmp((a)->fp_subtype_nm, (b)->fp_subtype_nm, PF_OSFP_LEN) == 0) - -/* handle pf_osfp_t packing */ -#define _FP_RESERVED_BIT 1 /* For the special negative #defines */ -#define _FP_UNUSED_BITS 1 -#define _FP_CLASS_BITS 10 /* OS Class (Windows, Linux) */ -#define _FP_VERSION_BITS 10 /* OS version (95, 98, NT, 2.4.54, 3.2) */ -#define _FP_SUBTYPE_BITS 10 /* patch level (NT SP4, SP3, ECN patch) */ -#define PF_OSFP_UNPACK(osfp, class, version, subtype) do { \ - (class) = ((osfp) >> (_FP_VERSION_BITS+_FP_SUBTYPE_BITS)) & \ - ((1 << _FP_CLASS_BITS) - 1); \ - (version) = ((osfp) >> _FP_SUBTYPE_BITS) & \ - ((1 << _FP_VERSION_BITS) - 1);\ - (subtype) = (osfp) & ((1 << _FP_SUBTYPE_BITS) - 1); \ -} while(0) -#define PF_OSFP_PACK(osfp, class, version, subtype) do { \ - (osfp) = ((class) & ((1 << _FP_CLASS_BITS) - 1)) << (_FP_VERSION_BITS \ - + _FP_SUBTYPE_BITS); \ - (osfp) |= ((version) & ((1 << _FP_VERSION_BITS) - 1)) << \ - _FP_SUBTYPE_BITS; \ - (osfp) |= (subtype) & ((1 << _FP_SUBTYPE_BITS) - 1); \ -} while(0) - -/* the fingerprint of an OSes TCP SYN packet */ -typedef u_int64_t pf_tcpopts_t; -struct pf_os_fingerprint { - SLIST_HEAD(pf_osfp_enlist, pf_osfp_entry) fp_oses; /* list of matches */ - pf_tcpopts_t fp_tcpopts; /* packed TCP options */ - u_int16_t fp_wsize; /* TCP window size */ - u_int16_t fp_psize; /* ip->ip_len */ - u_int16_t fp_mss; /* TCP MSS */ - u_int16_t fp_flags; -#define PF_OSFP_WSIZE_MOD 0x0001 /* Window modulus */ -#define PF_OSFP_WSIZE_DC 0x0002 /* Window don't care */ -#define PF_OSFP_WSIZE_MSS 0x0004 /* Window multiple of MSS */ -#define PF_OSFP_WSIZE_MTU 0x0008 /* Window multiple of MTU */ -#define PF_OSFP_PSIZE_MOD 0x0010 /* packet size modulus */ -#define PF_OSFP_PSIZE_DC 0x0020 /* packet size don't care */ -#define PF_OSFP_WSCALE 0x0040 /* TCP window scaling */ -#define PF_OSFP_WSCALE_MOD 0x0080 /* TCP window scale modulus */ -#define PF_OSFP_WSCALE_DC 0x0100 /* TCP window scale dont-care */ -#define PF_OSFP_MSS 0x0200 /* TCP MSS */ -#define PF_OSFP_MSS_MOD 0x0400 /* TCP MSS modulus */ -#define PF_OSFP_MSS_DC 0x0800 /* TCP MSS dont-care */ -#define PF_OSFP_DF 0x1000 /* IPv4 don't fragment bit */ -#define PF_OSFP_TS0 0x2000 /* Zero timestamp */ -#define PF_OSFP_INET6 0x4000 /* IPv6 */ - u_int8_t fp_optcnt; /* TCP option count */ - u_int8_t fp_wscale; /* TCP window scaling */ - u_int8_t fp_ttl; /* IPv4 TTL */ -#define PF_OSFP_MAXTTL_OFFSET 40 -/* TCP options packing */ -#define PF_OSFP_TCPOPT_NOP 0x0 /* TCP NOP option */ -#define PF_OSFP_TCPOPT_WSCALE 0x1 /* TCP window scaling option */ -#define PF_OSFP_TCPOPT_MSS 0x2 /* TCP max segment size opt */ -#define PF_OSFP_TCPOPT_SACK 0x3 /* TCP SACK OK option */ -#define PF_OSFP_TCPOPT_TS 0x4 /* TCP timestamp option */ -#define PF_OSFP_TCPOPT_BITS 3 /* bits used by each option */ -#define PF_OSFP_MAX_OPTS \ - (sizeof(((struct pf_os_fingerprint *)0)->fp_tcpopts) * 8) \ - / PF_OSFP_TCPOPT_BITS - - SLIST_ENTRY(pf_os_fingerprint) fp_next; -}; - -struct pf_osfp_ioctl { - struct pf_osfp_entry fp_os; - pf_tcpopts_t fp_tcpopts; /* packed TCP options */ - u_int16_t fp_wsize; /* TCP window size */ - u_int16_t fp_psize; /* ip->ip_len */ - u_int16_t fp_mss; /* TCP MSS */ - u_int16_t fp_flags; - u_int8_t fp_optcnt; /* TCP option count */ - u_int8_t fp_wscale; /* TCP window scaling */ - u_int8_t fp_ttl; /* IPv4 TTL */ - - int fp_getnum; /* DIOCOSFPGET number */ -}; - - -union pf_rule_ptr { - struct pf_rule *ptr; +union pf_krule_ptr { + struct pf_krule *ptr; u_int32_t nr; }; -#define PF_ANCHOR_NAME_SIZE 64 - -struct pf_rule { +struct pf_krule { struct pf_rule_addr src; struct pf_rule_addr dst; -#define PF_SKIP_IFP 0 -#define PF_SKIP_DIR 1 -#define PF_SKIP_AF 2 -#define PF_SKIP_PROTO 3 -#define PF_SKIP_SRC_ADDR 4 -#define PF_SKIP_SRC_PORT 5 -#define PF_SKIP_DST_ADDR 6 -#define PF_SKIP_DST_PORT 7 -#define PF_SKIP_COUNT 8 - union pf_rule_ptr skip[PF_SKIP_COUNT]; -#define PF_RULE_LABEL_SIZE 64 + union pf_krule_ptr skip[PF_SKIP_COUNT]; char label[PF_RULE_LABEL_SIZE]; char ifname[IFNAMSIZ]; char qname[PF_QNAME_SIZE]; char pqname[PF_QNAME_SIZE]; -#define PF_TAG_NAME_SIZE 64 char tagname[PF_TAG_NAME_SIZE]; char match_tagname[PF_TAG_NAME_SIZE]; char overload_tblname[PF_TABLE_NAME_SIZE]; - TAILQ_ENTRY(pf_rule) entries; - struct pf_pool rpool; + TAILQ_ENTRY(pf_krule) entries; + struct pf_kpool rpool; - u_int64_t evaluations; - u_int64_t packets[2]; - u_int64_t bytes[2]; + counter_u64_t evaluations; + counter_u64_t packets[2]; + counter_u64_t bytes[2]; - struct pfi_kif *kif; - struct pf_anchor *anchor; + struct pfi_kkif *kif; + struct pf_kanchor *anchor; struct pfr_ktable *overload_tbl; pf_osfp_t os_fingerprint; @@ -453,9 +274,6 @@ struct pf_rule { u_int8_t match_tag_not; u_int8_t natpass; -#define PF_STATE_NORMAL 0x1 -#define PF_STATE_MODULATE 0x2 -#define PF_STATE_SYNPROXY 0x3 u_int8_t keep_state; sa_family_t af; u_int8_t proto; @@ -472,11 +290,7 @@ struct pf_rule { u_int8_t anchor_relative; u_int8_t anchor_wildcard; -#define PF_FLUSH 0x01 -#define PF_FLUSH_GLOBAL 0x02 u_int8_t flush; -#define PF_PRIO_ZERO 0xff /* match "prio 0" packets */ -#define PF_PRIO_MAX 7 u_int8_t prio; u_int8_t set_prio[2]; @@ -484,55 +298,16 @@ struct pf_rule { struct pf_addr addr; u_int16_t port; } divert; - - uint64_t u_states_cur; - uint64_t u_states_tot; - uint64_t u_src_nodes; }; -/* rule flags */ -#define PFRULE_DROP 0x0000 -#define PFRULE_RETURNRST 0x0001 -#define PFRULE_FRAGMENT 0x0002 -#define PFRULE_RETURNICMP 0x0004 -#define PFRULE_RETURN 0x0008 -#define PFRULE_NOSYNC 0x0010 -#define PFRULE_SRCTRACK 0x0020 /* track source states */ -#define PFRULE_RULESRCTRACK 0x0040 /* per rule */ -#define PFRULE_REFS 0x0080 /* rule has references */ - -/* scrub flags */ -#define PFRULE_NODF 0x0100 -#define PFRULE_RANDOMID 0x0800 -#define PFRULE_REASSEMBLE_TCP 0x1000 -#define PFRULE_SET_TOS 0x2000 - -/* rule flags again */ -#define PFRULE_IFBOUND 0x00010000 /* if-bound */ -#define PFRULE_STATESLOPPY 0x00020000 /* sloppy state tracking */ - -#define PFSTATE_HIWAT 10000 /* default state table size */ -#define PFSTATE_ADAPT_START 6000 /* default adaptive timeout start */ -#define PFSTATE_ADAPT_END 12000 /* default adaptive timeout end */ - - -struct pf_threshold { - u_int32_t limit; -#define PF_THRESHOLD_MULT 1000 -#define PF_THRESHOLD_MAX 0xffffffff / PF_THRESHOLD_MULT - u_int32_t seconds; - u_int32_t count; - u_int32_t last; -}; - -struct pf_src_node { - LIST_ENTRY(pf_src_node) entry; +struct pf_ksrc_node { + LIST_ENTRY(pf_ksrc_node) entry; struct pf_addr addr; struct pf_addr raddr; - union pf_rule_ptr rule; - struct pfi_kif *kif; - u_int64_t bytes[2]; - u_int64_t packets[2]; + union pf_krule_ptr rule; + struct pfi_kkif *kif; + counter_u64_t bytes[2]; + counter_u64_t packets[2]; u_int32_t states; u_int32_t conn; struct pf_threshold conn_rate; @@ -541,8 +316,7 @@ struct pf_src_node { sa_family_t af; u_int8_t ruletype; }; - -#define PFSNODE_HIWAT 10000 /* default source node table size */ +#endif struct pf_state_scrub { struct timeval pfss_last; /* time received last packet */ @@ -607,6 +381,15 @@ struct pf_state_cmp { u_int8_t pad[3]; }; +#define PFSTATE_ALLOWOPTS 0x01 +#define PFSTATE_SLOPPY 0x02 +/* was PFSTATE_PFLOW 0x04 */ +#define PFSTATE_NOSYNC 0x08 +#define PFSTATE_ACK 0x10 +#define PFSTATE_SETPRIO 0x0200 +#define PFSTATE_SETMASK (PFSTATE_SETPRIO) + +#ifdef _KERNEL struct pf_state { u_int64_t id; u_int32_t creatorid; @@ -619,30 +402,23 @@ struct pf_state { LIST_ENTRY(pf_state) entry; struct pf_state_peer src; struct pf_state_peer dst; - union pf_rule_ptr rule; - union pf_rule_ptr anchor; - union pf_rule_ptr nat_rule; + union pf_krule_ptr rule; + union pf_krule_ptr anchor; + union pf_krule_ptr nat_rule; struct pf_addr rt_addr; struct pf_state_key *key[2]; /* addresses stack and wire */ - struct pfi_kif *kif; - struct pfi_kif *rt_kif; - struct pf_src_node *src_node; - struct pf_src_node *nat_src_node; - u_int64_t packets[2]; - u_int64_t bytes[2]; + struct pfi_kkif *kif; + struct pfi_kkif *rt_kif; + struct pf_ksrc_node *src_node; + struct pf_ksrc_node *nat_src_node; + counter_u64_t packets[2]; + counter_u64_t bytes[2]; u_int32_t creation; u_int32_t expire; u_int32_t pfsync_time; u_int16_t tag; u_int8_t log; u_int8_t state_flags; -#define PFSTATE_ALLOWOPTS 0x01 -#define PFSTATE_SLOPPY 0x02 -/* was PFSTATE_PFLOW 0x04 */ -#define PFSTATE_NOSYNC 0x08 -#define PFSTATE_ACK 0x10 -#define PFSTATE_SETPRIO 0x0200 -#define PFSTATE_SETMASK (PFSTATE_SETPRIO) u_int8_t timeout; u_int8_t sync_state; /* PFSYNC_S_x */ @@ -650,6 +426,7 @@ struct pf_state { u_int8_t sync_updates; u_int8_t _tail[3]; }; +#endif /* * Unified state structures for pulling states out of the kernel @@ -759,42 +536,42 @@ struct pfsync_state { d += ntohl(s[1]); \ } while (0) -TAILQ_HEAD(pf_rulequeue, pf_rule); +TAILQ_HEAD(pf_krulequeue, pf_krule); -struct pf_anchor; +struct pf_kanchor; -struct pf_ruleset { +struct pf_kruleset { struct { - struct pf_rulequeue queues[2]; + struct pf_krulequeue queues[2]; struct { - struct pf_rulequeue *ptr; - struct pf_rule **ptr_array; + struct pf_krulequeue *ptr; + struct pf_krule **ptr_array; u_int32_t rcount; u_int32_t ticket; int open; } active, inactive; } rules[PF_RULESET_MAX]; - struct pf_anchor *anchor; + struct pf_kanchor *anchor; u_int32_t tticket; int tables; int topen; }; -RB_HEAD(pf_anchor_global, pf_anchor); -RB_HEAD(pf_anchor_node, pf_anchor); -struct pf_anchor { - RB_ENTRY(pf_anchor) entry_global; - RB_ENTRY(pf_anchor) entry_node; - struct pf_anchor *parent; - struct pf_anchor_node children; +RB_HEAD(pf_kanchor_global, pf_kanchor); +RB_HEAD(pf_kanchor_node, pf_kanchor); +struct pf_kanchor { + RB_ENTRY(pf_kanchor) entry_global; + RB_ENTRY(pf_kanchor) entry_node; + struct pf_kanchor *parent; + struct pf_kanchor_node children; char name[PF_ANCHOR_NAME_SIZE]; char path[MAXPATHLEN]; - struct pf_ruleset ruleset; + struct pf_kruleset ruleset; int refcnt; /* anchor rules */ int match; /* XXX: used for pfctl black magic */ }; -RB_PROTOTYPE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare); -RB_PROTOTYPE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare); +RB_PROTOTYPE(pf_kanchor_global, pf_kanchor, entry_global, pf_anchor_compare); +RB_PROTOTYPE(pf_kanchor_node, pf_kanchor, entry_node, pf_kanchor_compare); #define PF_RESERVED_ANCHOR "_pf" @@ -821,7 +598,7 @@ RB_PROTOTYPE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare); PFR_TFLAG_REFDANCHOR | \ PFR_TFLAG_COUNTERS) -struct pf_anchor_stackframe; +struct pf_kanchor_stackframe; struct pfr_table { char pfrt_anchor[MAXPATHLEN]; @@ -849,6 +626,8 @@ struct pfr_addr { enum { PFR_DIR_IN, PFR_DIR_OUT, PFR_DIR_MAX }; enum { PFR_OP_BLOCK, PFR_OP_PASS, PFR_OP_ADDR_MAX, PFR_OP_TABLE_MAX }; +enum { PFR_TYPE_PACKETS, PFR_TYPE_BYTES, PFR_TYPE_MAX }; +#define PFR_NUM_COUNTERS (PFR_DIR_MAX * PFR_OP_ADDR_MAX * PFR_TYPE_MAX) #define PFR_OP_XPASS PFR_OP_ADDR_MAX struct pfr_astats { @@ -870,6 +649,17 @@ struct pfr_tstats { int pfrts_cnt; int pfrts_refcnt[PFR_REFCNT_MAX]; }; + +struct pfr_ktstats { + struct pfr_table pfrts_t; + counter_u64_t pfrkts_packets[PFR_DIR_MAX][PFR_OP_TABLE_MAX]; + counter_u64_t pfrkts_bytes[PFR_DIR_MAX][PFR_OP_TABLE_MAX]; + counter_u64_t pfrkts_match; + counter_u64_t pfrkts_nomatch; + long pfrkts_tzero; + int pfrkts_cnt; + int pfrkts_refcnt[PFR_REFCNT_MAX]; +}; #define pfrts_name pfrts_t.pfrt_name #define pfrts_flags pfrts_t.pfrt_flags @@ -883,17 +673,20 @@ union sockaddr_union { #endif /* _SOCKADDR_UNION_DEFINED */ struct pfr_kcounters { - u_int64_t pfrkc_packets[PFR_DIR_MAX][PFR_OP_ADDR_MAX]; - u_int64_t pfrkc_bytes[PFR_DIR_MAX][PFR_OP_ADDR_MAX]; + counter_u64_t pfrkc_counters; + long pfrkc_tzero; }; +#define pfr_kentry_counter(kc, dir, op, t) \ + ((kc)->pfrkc_counters + \ + (dir) * PFR_OP_ADDR_MAX * PFR_TYPE_MAX + (op) * PFR_TYPE_MAX + (t)) +#ifdef _KERNEL SLIST_HEAD(pfr_kentryworkq, pfr_kentry); struct pfr_kentry { struct radix_node pfrke_node[2]; union sockaddr_union pfrke_sa; SLIST_ENTRY(pfr_kentry) pfrke_workq; - struct pfr_kcounters *pfrke_counters; - long pfrke_tzero; + struct pfr_kcounters pfrke_counters; u_int8_t pfrke_af; u_int8_t pfrke_net; u_int8_t pfrke_not; @@ -903,45 +696,42 @@ struct pfr_kentry { SLIST_HEAD(pfr_ktableworkq, pfr_ktable); RB_HEAD(pfr_ktablehead, pfr_ktable); struct pfr_ktable { - struct pfr_tstats pfrkt_ts; + struct pfr_ktstats pfrkt_kts; RB_ENTRY(pfr_ktable) pfrkt_tree; SLIST_ENTRY(pfr_ktable) pfrkt_workq; struct radix_node_head *pfrkt_ip4; struct radix_node_head *pfrkt_ip6; struct pfr_ktable *pfrkt_shadow; struct pfr_ktable *pfrkt_root; - struct pf_ruleset *pfrkt_rs; + struct pf_kruleset *pfrkt_rs; long pfrkt_larg; int pfrkt_nflags; }; -#define pfrkt_t pfrkt_ts.pfrts_t +#define pfrkt_t pfrkt_kts.pfrts_t #define pfrkt_name pfrkt_t.pfrt_name #define pfrkt_anchor pfrkt_t.pfrt_anchor #define pfrkt_ruleset pfrkt_t.pfrt_ruleset #define pfrkt_flags pfrkt_t.pfrt_flags -#define pfrkt_cnt pfrkt_ts.pfrts_cnt -#define pfrkt_refcnt pfrkt_ts.pfrts_refcnt -#define pfrkt_packets pfrkt_ts.pfrts_packets -#define pfrkt_bytes pfrkt_ts.pfrts_bytes -#define pfrkt_match pfrkt_ts.pfrts_match -#define pfrkt_nomatch pfrkt_ts.pfrts_nomatch -#define pfrkt_tzero pfrkt_ts.pfrts_tzero +#define pfrkt_cnt pfrkt_kts.pfrkts_cnt +#define pfrkt_refcnt pfrkt_kts.pfrkts_refcnt +#define pfrkt_packets pfrkt_kts.pfrkts_packets +#define pfrkt_bytes pfrkt_kts.pfrkts_bytes +#define pfrkt_match pfrkt_kts.pfrkts_match +#define pfrkt_nomatch pfrkt_kts.pfrkts_nomatch +#define pfrkt_tzero pfrkt_kts.pfrkts_tzero +#endif -/* keep synced with pfi_kif, used in RB_FIND */ -struct pfi_kif_cmp { - char pfik_name[IFNAMSIZ]; -}; - -struct pfi_kif { +#ifdef _KERNEL +struct pfi_kkif { char pfik_name[IFNAMSIZ]; union { - RB_ENTRY(pfi_kif) _pfik_tree; - LIST_ENTRY(pfi_kif) _pfik_list; + RB_ENTRY(pfi_kkif) _pfik_tree; + LIST_ENTRY(pfi_kkif) _pfik_list; } _pfik_glue; #define pfik_tree _pfik_glue._pfik_tree #define pfik_list _pfik_glue._pfik_list - u_int64_t pfik_packets[2][2][2]; - u_int64_t pfik_bytes[2][2][2]; + counter_u64_t pfik_packets[2][2][2]; + counter_u64_t pfik_bytes[2][2][2]; u_int32_t pfik_tzero; u_int pfik_flags; struct ifnet *pfik_ifp; @@ -949,6 +739,7 @@ struct pfi_kif { u_int pfik_rulerefs; TAILQ_HEAD(, pfi_dynaddr) pfik_dynaddrs; }; +#endif #define PFI_IFLAG_REFS 0x0001 /* has state references */ #define PFI_IFLAG_SKIP 0x0100 /* skip filtering on interface */ @@ -970,7 +761,7 @@ struct pf_pdesc { void *any; } hdr; - struct pf_rule *nat_rule; /* nat/rdr rule applied to packet */ + struct pf_krule *nat_rule; /* nat/rdr rule applied to packet */ struct pf_addr *src; /* src address */ struct pf_addr *dst; /* dst address */ u_int16_t *sport; @@ -1065,6 +856,19 @@ struct pf_divert { #define PFFRAG_FRENT_HIWAT 5000 /* Number of fragment entries */ #define PFR_KENTRY_HIWAT 200000 /* Number of table entries */ +/* + * Limit the length of the fragment queue traversal. Remember + * search entry points based on the fragment offset. + */ +#define PF_FRAG_ENTRY_POINTS 16 + +/* + * The number of entries in the fragment queue must be limited + * to avoid DoS by linear seaching. Instead of a global limit, + * use a limit per entry point. For large packets these sum up. + */ +#define PF_FRAG_ENTRY_LIMIT 64 + /* * ioctl parameter structures */ @@ -1161,14 +965,33 @@ struct pfioc_limit { unsigned limit; }; -struct pfioc_altq { +struct pfioc_altq_v0 { u_int32_t action; u_int32_t ticket; u_int32_t nr; - struct pf_altq altq; + struct pf_altq_v0 altq; }; -struct pfioc_qstats { +struct pfioc_altq_v1 { + u_int32_t action; + u_int32_t ticket; + u_int32_t nr; + /* + * Placed here so code that only uses the above parameters can be + * written entirely in terms of the v0 or v1 type. + */ + u_int32_t version; + struct pf_altq_v1 altq; +}; + +/* + * Latest version of struct pfioc_altq_vX. This must move in lock-step with + * the latest version of struct pf_altq_vX as it has that struct as a + * member. + */ +#define PFIOC_ALTQ_VERSION PF_ALTQ_VERSION + +struct pfioc_qstats_v0 { u_int32_t ticket; u_int32_t nr; void *buf; @@ -1176,6 +999,22 @@ struct pfioc_qstats { u_int8_t scheduler; }; +struct pfioc_qstats_v1 { + u_int32_t ticket; + u_int32_t nr; + void *buf; + int nbytes; + u_int8_t scheduler; + /* + * Placed here so code that only uses the above parameters can be + * written entirely in terms of the v0 or v1 type. + */ + u_int32_t version; /* Requested version of stats struct */ +}; + +/* Latest version of struct pfioc_qstats_vX */ +#define PFIOC_QSTATS_VERSION 1 + struct pfioc_ruleset { u_int32_t nr; char path[MAXPATHLEN]; @@ -1231,7 +1070,6 @@ struct pfioc_iface { int pfiio_flags; }; - /* * ioctl operations */ @@ -1261,11 +1099,16 @@ struct pfioc_iface { #define DIOCKILLSTATES _IOWR('D', 41, struct pfioc_state_kill) #define DIOCSTARTALTQ _IO ('D', 42) #define DIOCSTOPALTQ _IO ('D', 43) -#define DIOCADDALTQ _IOWR('D', 45, struct pfioc_altq) -#define DIOCGETALTQS _IOWR('D', 47, struct pfioc_altq) -#define DIOCGETALTQ _IOWR('D', 48, struct pfioc_altq) -#define DIOCCHANGEALTQ _IOWR('D', 49, struct pfioc_altq) -#define DIOCGETQSTATS _IOWR('D', 50, struct pfioc_qstats) +#define DIOCADDALTQV0 _IOWR('D', 45, struct pfioc_altq_v0) +#define DIOCADDALTQV1 _IOWR('D', 45, struct pfioc_altq_v1) +#define DIOCGETALTQSV0 _IOWR('D', 47, struct pfioc_altq_v0) +#define DIOCGETALTQSV1 _IOWR('D', 47, struct pfioc_altq_v1) +#define DIOCGETALTQV0 _IOWR('D', 48, struct pfioc_altq_v0) +#define DIOCGETALTQV1 _IOWR('D', 48, struct pfioc_altq_v1) +#define DIOCCHANGEALTQV0 _IOWR('D', 49, struct pfioc_altq_v0) +#define DIOCCHANGEALTQV1 _IOWR('D', 49, struct pfioc_altq_v1) +#define DIOCGETQSTATSV0 _IOWR('D', 50, struct pfioc_qstats_v0) +#define DIOCGETQSTATSV1 _IOWR('D', 50, struct pfioc_qstats_v1) #define DIOCBEGINADDRS _IOWR('D', 51, struct pfioc_pooladdr) #define DIOCADDADDR _IOWR('D', 52, struct pfioc_pooladdr) #define DIOCGETADDRS _IOWR('D', 53, struct pfioc_pooladdr) @@ -1303,10 +1146,22 @@ struct pfioc_iface { #define DIOCSETIFFLAG _IOWR('D', 89, struct pfioc_iface) #define DIOCCLRIFFLAG _IOWR('D', 90, struct pfioc_iface) #define DIOCKILLSRCNODES _IOWR('D', 91, struct pfioc_src_node_kill) -struct pf_ifspeed { +struct pf_ifspeed_v0 { char ifname[IFNAMSIZ]; u_int32_t baudrate; }; -#define DIOCGIFSPEED _IOWR('D', 92, struct pf_ifspeed) + +struct pf_ifspeed_v1 { + char ifname[IFNAMSIZ]; + u_int32_t baudrate32; + /* layout identical to struct pf_ifspeed_v0 up to this point */ + u_int64_t baudrate; +}; + +/* Latest version of struct pf_ifspeed_vX */ +#define PF_IFSPEED_VERSION 1 + +#define DIOCGIFSPEEDV0 _IOWR('D', 92, struct pf_ifspeed_v0) +#define DIOCGIFSPEEDV1 _IOWR('D', 92, struct pf_ifspeed_v1) #endif /* _NET_PFVAR_H_ */ diff --git a/tools/compat/include/net/radix.h b/tools/compat/include/net/radix.h index 8277b0c49..a0e5e5c5a 100644 --- a/tools/compat/include/net/radix.h +++ b/tools/compat/include/net/radix.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1988, 1989, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -33,6 +35,16 @@ #ifndef _RADIX_H_ #define _RADIX_H_ +#ifdef _KERNEL +#include +#include +#include +#endif + +#ifdef MALLOC_DECLARE +MALLOC_DECLARE(M_RTABLE); +#endif + /* * Radix search tree node layout. */ @@ -126,7 +138,7 @@ struct radix_node_head { rn_close_t *rnh_close; /*do something when the last ref drops*/ struct radix_node rnh_nodes[3]; /* empty tree for common case */ #ifdef _KERNEL - struct rwlock rnh_lock; /* locks entire radix tree */ + struct rmlock rnh_lock; /* locks entire radix tree */ #endif }; @@ -147,18 +159,31 @@ void rn_inithead_internal(struct radix_head *rh, struct radix_node *base_nodes, #define R_Zalloc(p, t, n) (p = (t) malloc((unsigned long)(n), M_RTABLE, M_NOWAIT | M_ZERO)) #define R_Free(p) free((caddr_t)p, M_RTABLE); +#define RADIX_NODE_HEAD_RLOCK_TRACKER struct rm_priotracker _rnh_tracker #define RADIX_NODE_HEAD_LOCK_INIT(rnh) \ - rw_init_flags(&(rnh)->rnh_lock, "radix node head", 0) -#define RADIX_NODE_HEAD_LOCK(rnh) rw_wlock(&(rnh)->rnh_lock) -#define RADIX_NODE_HEAD_UNLOCK(rnh) rw_wunlock(&(rnh)->rnh_lock) -#define RADIX_NODE_HEAD_RLOCK(rnh) rw_rlock(&(rnh)->rnh_lock) -#define RADIX_NODE_HEAD_RUNLOCK(rnh) rw_runlock(&(rnh)->rnh_lock) -#define RADIX_NODE_HEAD_LOCK_TRY_UPGRADE(rnh) rw_try_upgrade(&(rnh)->rnh_lock) - - -#define RADIX_NODE_HEAD_DESTROY(rnh) rw_destroy(&(rnh)->rnh_lock) -#define RADIX_NODE_HEAD_LOCK_ASSERT(rnh) rw_assert(&(rnh)->rnh_lock, RA_LOCKED) -#define RADIX_NODE_HEAD_WLOCK_ASSERT(rnh) rw_assert(&(rnh)->rnh_lock, RA_WLOCKED) + rm_init(&(rnh)->rnh_lock, "radix node head") +#define RADIX_NODE_HEAD_LOCK(rnh) rm_wlock(&(rnh)->rnh_lock) +#define RADIX_NODE_HEAD_UNLOCK(rnh) rm_wunlock(&(rnh)->rnh_lock) +#define RADIX_NODE_HEAD_RLOCK(rnh) rm_rlock(&(rnh)->rnh_lock,\ + &_rnh_tracker) +#define RADIX_NODE_HEAD_RUNLOCK(rnh) rm_runlock(&(rnh)->rnh_lock,\ + &_rnh_tracker) +#define RADIX_NODE_HEAD_DESTROY(rnh) rm_destroy(&(rnh)->rnh_lock) +#define RADIX_NODE_HEAD_LOCK_ASSERT(rnh) rm_assert(&(rnh)->rnh_lock, RA_LOCKED) +#define RADIX_NODE_HEAD_WLOCK_ASSERT(rnh) rm_assert(&(rnh)->rnh_lock, RA_WLOCKED) #endif /* _KERNEL */ +int rn_inithead(void **, int); +int rn_detachhead(void **); +int rn_refines(void *, void *); +struct radix_node *rn_addroute(void *, void *, struct radix_head *, + struct radix_node[2]); +struct radix_node *rn_delete(void *, void *, struct radix_head *); +struct radix_node *rn_lookup (void *v_arg, void *m_arg, + struct radix_head *head); +struct radix_node *rn_match(void *, struct radix_head *); +int rn_walktree_from(struct radix_head *h, void *a, void *m, + walktree_f_t *f, void *w); +int rn_walktree(struct radix_head *, walktree_f_t *, void *); + #endif /* _RADIX_H_ */ diff --git a/tools/compat/include/net/route.h b/tools/compat/include/net/route.h index 3f3e3f6a8..02285a025 100644 --- a/tools/compat/include/net/route.h +++ b/tools/compat/include/net/route.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1980, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -46,7 +48,7 @@ * with its length. */ struct route { - struct rtentry *ro_rt; + struct nhop_object *ro_nh; struct llentry *ro_lle; /* * ro_prepend and ro_plen are only used for bpf to pass in a @@ -64,8 +66,6 @@ struct route { #define RT_MAY_LOOP_BIT 3 /* dst may require loop copy */ #define RT_HAS_HEADER_BIT 4 /* mbuf already have its header prepended */ -#define RT_CACHING_CONTEXT 0x1 /* XXX: not used anywhere */ -#define RT_NORTREF 0x2 /* doesn't hold reference on ro_rt */ #define RT_L2_ME (1 << RT_L2_ME_BIT) /* 0x0004 */ #define RT_MAY_LOOP (1 << RT_MAY_LOOP_BIT) /* 0x0008 */ #define RT_HAS_HEADER (1 << RT_HAS_HEADER_BIT) /* 0x0010 */ @@ -87,7 +87,8 @@ struct rt_metrics { u_long rmx_rttvar; /* estimated rtt variance */ u_long rmx_pksent; /* packets sent using this route */ u_long rmx_weight; /* route weight */ - u_long rmx_filler[3]; /* will be used for T/TCP later */ + u_long rmx_nhidx; /* route nexhop index */ + u_long rmx_filler[2]; /* will be used for T/TCP later */ }; /* @@ -101,6 +102,10 @@ struct rt_metrics { /* lle state is exported in rmx_state rt_metrics field */ #define rmx_state rmx_weight +/* default route weight */ +#define RT_DEFAULT_WEIGHT 1 +#define RT_MAX_WEIGHT 16777215 /* 3 bytes */ + /* * Keep a generation count of routing table, incremented on route addition, * so we can invalidate caches. This is accessed without a lock, as precision @@ -111,35 +116,57 @@ typedef volatile u_int rt_gen_t; /* tree generation (for adds) */ #define RT_DEFAULT_FIB 0 /* Explicitly mark fib=0 restricted cases */ #define RT_ALL_FIBS -1 /* Announce event for every fib */ +#ifdef _KERNEL +VNET_DECLARE(uint32_t, _rt_numfibs); /* number of existing route tables */ +#define V_rt_numfibs VNET(_rt_numfibs) +/* temporary compat arg */ +#define rt_numfibs V_rt_numfibs +VNET_DECLARE(u_int, rt_add_addr_allfibs); /* Announce interfaces to all fibs */ +#define V_rt_add_addr_allfibs VNET(rt_add_addr_allfibs) -#include "net/radix.h" +/* Calculate flowid for locally-originated packets */ +#define V_fib_hash_outbound VNET(fib_hash_outbound) +VNET_DECLARE(u_int, fib_hash_outbound); -#if defined(_KERNEL) || defined(_WANT_RTENTRY) -struct rtentry { - struct radix_node rt_nodes[2]; /* tree glue, and other values */ - /* - * XXX struct rtentry must begin with a struct radix_node (or two!) - * because the code does some casts of a 'struct radix_node *' - * to a 'struct rtentry *' - */ -#define rt_key(r) (*((struct sockaddr **)(&(r)->rt_nodes->rn_key))) -#define rt_mask(r) (*((struct sockaddr **)(&(r)->rt_nodes->rn_mask))) - struct sockaddr *rt_gateway; /* value */ - struct ifnet *rt_ifp; /* the answer: interface to use */ - struct ifaddr *rt_ifa; /* the answer: interface address to use */ - int rt_flags; /* up/down?, host/net */ - int rt_refcnt; /* # held references */ - u_int rt_fibnum; /* which FIB */ - u_long rt_mtu; /* MTU for this path */ - u_long rt_weight; /* absolute weight */ - u_long rt_expire; /* lifetime for route, e.g. redirect */ -#define rt_endzero rt_pksent - counter_u64_t rt_pksent; /* packets sent using this route */ - struct mtx rt_mtx; /* mutex for routing entry */ - struct rtentry *rt_chain; /* pointer to next rtentry to delete */ -}; -#endif /* _KERNEL || _WANT_RTENTRY */ +/* Outbound flowid generation rules */ +#ifdef RSS +#define fib4_calc_packet_hash xps_proto_software_hash_v4 +#define fib6_calc_packet_hash xps_proto_software_hash_v6 +#define CALC_FLOWID_OUTBOUND_SENDTO true + +#ifdef ROUTE_MPATH +#define CALC_FLOWID_OUTBOUND V_fib_hash_outbound +#else +#define CALC_FLOWID_OUTBOUND false +#endif + +#else /* !RSS */ + +#define fib4_calc_packet_hash fib4_calc_software_hash +#define fib6_calc_packet_hash fib6_calc_software_hash + +#ifdef ROUTE_MPATH +#define CALC_FLOWID_OUTBOUND_SENDTO V_fib_hash_outbound +#define CALC_FLOWID_OUTBOUND V_fib_hash_outbound +#else +#define CALC_FLOWID_OUTBOUND_SENDTO false +#define CALC_FLOWID_OUTBOUND false +#endif + +#endif /* RSS */ + + +#endif /* _KERNEL */ + +/* + * We distinguish between routes to hosts and routes to networks, + * preferring the former if available. For each route we infer + * the interface to use from the gateway address supplied when + * the route was entered. Routes that forward packets through + * gateways are marked so that the output routines know to address the + * gateway rather than the ultimate destination. + */ #define RTF_UP 0x1 /* route usable */ #define RTF_GATEWAY 0x2 /* destination is a gateway */ #define RTF_HOST 0x4 /* host entry (net otherwise) */ @@ -168,7 +195,7 @@ struct rtentry { /* 0x8000000 and up unassigned */ #define RTF_STICKY 0x10000000 /* always route dst->src */ -#define RTF_RNH_LOCKED 0x40000000 /* unused */ +#define RTF_RNH_LOCKED 0x40000000 /* radix node head is locked */ #define RTF_GWFLAG_COMPAT 0x80000000 /* a compatibility bit for interacting with existing routing apps */ @@ -183,45 +210,41 @@ struct rtentry { */ /* Consumer-visible nexthop info flags */ +#define NHF_MULTIPATH 0x0008 /* Nexhop is a nexthop group */ #define NHF_REJECT 0x0010 /* RTF_REJECT */ #define NHF_BLACKHOLE 0x0020 /* RTF_BLACKHOLE */ #define NHF_REDIRECT 0x0040 /* RTF_DYNAMIC|RTF_MODIFIED */ #define NHF_DEFAULT 0x0080 /* Default route */ #define NHF_BROADCAST 0x0100 /* RTF_BROADCAST */ #define NHF_GATEWAY 0x0200 /* RTF_GATEWAY */ +#define NHF_HOST 0x0400 /* RTF_HOST */ /* Nexthop request flags */ -#define NHR_IFAIF 0x01 /* Return ifa_ifp interface */ -#define NHR_REF 0x02 /* For future use */ +#define NHR_NONE 0x00 /* empty flags field */ +#define NHR_REF 0x01 /* reference nexhop */ +#define NHR_NODEFAULT 0x02 /* uRPF: do not consider default route */ /* Control plane route request flags */ #define NHR_COPY 0x100 /* Copy rte data */ - -#ifdef _KERNEL -/* rte<>ro_flags translation */ -static inline void -rt_update_ro_flags(struct route *ro) -{ - int rt_flags = ro->ro_rt->rt_flags; - - ro->ro_flags &= ~ (RT_REJECT|RT_BLACKHOLE|RT_HAS_GW); - - ro->ro_flags |= (rt_flags & RTF_REJECT) ? RT_REJECT : 0; - ro->ro_flags |= (rt_flags & RTF_BLACKHOLE) ? RT_BLACKHOLE : 0; - ro->ro_flags |= (rt_flags & RTF_GATEWAY) ? RT_HAS_GW : 0; -} -#endif +#define NHR_UNLOCKED 0x200 /* Do not lock table */ /* * Routing statistics. */ -struct rtstat { - short rts_badredirect; /* bogus redirect calls */ - short rts_dynamic; /* routes created by redirects */ - short rts_newgateway; /* routes modified by redirects */ - short rts_unreach; /* lookups which failed */ - short rts_wildcard; /* lookups satisfied by a wildcard */ +struct rtstat { + uint64_t rts_badredirect; /* bogus redirect calls */ + uint64_t rts_dynamic; /* routes created by redirects */ + uint64_t rts_newgateway; /* routes modified by redirects */ + uint64_t rts_unreach; /* lookups which failed */ + uint64_t rts_wildcard; /* lookups satisfied by a wildcard */ + uint64_t rts_nh_idx_alloc_failure; /* nexthop index alloc failure*/ + uint64_t rts_nh_alloc_failure; /* nexthop allocation failure*/ + uint64_t rts_add_failure; /* # of route addition failures */ + uint64_t rts_add_retry; /* # of route addition retries */ + uint64_t rts_del_failure; /* # of route deletion failure */ + uint64_t rts_del_retry; /* # of route deletion retries */ }; + /* * Structures for routing messages. */ @@ -230,6 +253,7 @@ struct rt_msghdr { u_char rtm_version; /* future binary compatibility */ u_char rtm_type; /* message type */ u_short rtm_index; /* index for associated ifp */ + u_short _rtm_spare1; int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ int rtm_addrs; /* bitmask identifying sockaddrs in msg */ pid_t rtm_pid; /* identify sender */ @@ -244,25 +268,35 @@ struct rt_msghdr { /* * Message types. + * + * The format for each message is annotated below using the following + * identifiers: + * + * (1) struct rt_msghdr + * (2) struct ifa_msghdr + * (3) struct if_msghdr + * (4) struct ifma_msghdr + * (5) struct if_announcemsghdr + * */ -#define RTM_ADD 0x1 /* Add Route */ -#define RTM_DELETE 0x2 /* Delete Route */ -#define RTM_CHANGE 0x3 /* Change Metrics or flags */ -#define RTM_GET 0x4 /* Report Metrics */ -#define RTM_LOSING 0x5 /* Kernel Suspects Partitioning */ -#define RTM_REDIRECT 0x6 /* Told to use different route */ -#define RTM_MISS 0x7 /* Lookup failed on this address */ -#define RTM_LOCK 0x8 /* fix specified metrics */ +#define RTM_ADD 0x1 /* (1) Add Route */ +#define RTM_DELETE 0x2 /* (1) Delete Route */ +#define RTM_CHANGE 0x3 /* (1) Change Metrics or flags */ +#define RTM_GET 0x4 /* (1) Report Metrics */ +#define RTM_LOSING 0x5 /* (1) Kernel Suspects Partitioning */ +#define RTM_REDIRECT 0x6 /* (1) Told to use different route */ +#define RTM_MISS 0x7 /* (1) Lookup failed on this address */ +#define RTM_LOCK 0x8 /* (1) fix specified metrics */ /* 0x9 */ /* 0xa */ -#define RTM_RESOLVE 0xb /* req to resolve dst to LL addr */ -#define RTM_NEWADDR 0xc /* address being added to iface */ -#define RTM_DELADDR 0xd /* address being removed from iface */ -#define RTM_IFINFO 0xe /* iface going up/down etc. */ -#define RTM_NEWMADDR 0xf /* mcast group membership being added to if */ -#define RTM_DELMADDR 0x10 /* mcast group membership being deleted */ -#define RTM_IFANNOUNCE 0x11 /* iface arrival/departure */ -#define RTM_IEEE80211 0x12 /* IEEE80211 wireless event */ +#define RTM_RESOLVE 0xb /* (1) req to resolve dst to LL addr */ +#define RTM_NEWADDR 0xc /* (2) address being added to iface */ +#define RTM_DELADDR 0xd /* (2) address being removed from iface */ +#define RTM_IFINFO 0xe /* (3) iface going up/down etc. */ +#define RTM_NEWMADDR 0xf /* (4) mcast group membership being added to if */ +#define RTM_DELMADDR 0x10 /* (4) mcast group membership being deleted */ +#define RTM_IFANNOUNCE 0x11 /* (5) iface arrival/departure */ +#define RTM_IEEE80211 0x12 /* (5) IEEE80211 wireless event */ /* * Bitmask values for rtm_inits and rmx_locks. @@ -302,7 +336,10 @@ struct rt_msghdr { #define RTAX_BRD 7 /* for NEWADDR, broadcast or p-p dest addr */ #define RTAX_MAX 8 /* size of array to allocate */ -typedef int rt_filter_f_t(const struct rtentry *, void *); +struct rtentry; +struct nhop_object; +typedef int rib_filter_f_t(const struct rtentry *, const struct nhop_object *, + void *); struct rt_addrinfo { int rti_addrs; /* Route RTF_ flags */ @@ -310,7 +347,7 @@ struct rt_addrinfo { struct sockaddr *rti_info[RTAX_MAX]; /* Sockaddr data */ struct ifaddr *rti_ifa; /* value of rt_ifa addr */ struct ifnet *rti_ifp; /* route interface */ - rt_filter_f_t *rti_filter; /* filter function */ + rib_filter_f_t *rti_filter; /* filter function */ void *rti_filterdata; /* filter paramenters */ u_long rti_mflags; /* metrics RTV_ flags */ u_long rti_spare; /* Will be used for fib */ @@ -321,11 +358,10 @@ struct rt_addrinfo { * This macro returns the size of a struct sockaddr when passed * through a routing socket. Basically we round up sa_len to * a multiple of sizeof(long), with a minimum of sizeof(long). - * The check for a NULL pointer is just a convenience, probably never used. * The case sa_len == 0 should only apply to empty structures. */ #define SA_SIZE(sa) \ - ( (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \ + ( (((struct sockaddr *)(sa))->sa_len == 0) ? \ sizeof(long) : \ 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) ) @@ -333,4 +369,79 @@ struct rt_addrinfo { (((const struct sockaddr *)(a))->sa_len == ((const struct sockaddr *)(b))->sa_len) && \ (bcmp((a), (b), ((const struct sockaddr *)(b))->sa_len) == 0)) +#ifdef _KERNEL + +#define RT_LINK_IS_UP(ifp) (!((ifp)->if_capabilities & IFCAP_LINKSTATE) \ + || (ifp)->if_link_state == LINK_STATE_UP) + +#define RO_NHFREE(_ro) do { \ + if ((_ro)->ro_nh) { \ + NH_FREE((_ro)->ro_nh); \ + (_ro)->ro_nh = NULL; \ + } \ +} while (0) + +#define RO_INVALIDATE_CACHE(ro) do { \ + if ((ro)->ro_lle != NULL) { \ + LLE_FREE((ro)->ro_lle); \ + (ro)->ro_lle = NULL; \ + } \ + if ((ro)->ro_nh != NULL) { \ + NH_FREE((ro)->ro_nh); \ + (ro)->ro_nh = NULL; \ + } \ + } while (0) + +/* + * Validate a cached route based on a supplied cookie. If there is an + * out-of-date cache, simply free it. Update the generation number + * for the new allocation + */ +#define NH_VALIDATE(ro, cookiep, fibnum) do { \ + rt_gen_t cookie = RT_GEN(fibnum, (ro)->ro_dst.sa_family); \ + if (*(cookiep) != cookie) { \ + RO_INVALIDATE_CACHE(ro); \ + *(cookiep) = cookie; \ + } \ +} while (0) + +struct ifmultiaddr; +struct rib_head; + +void rt_ieee80211msg(struct ifnet *, int, void *, size_t); +void rt_ifannouncemsg(struct ifnet *, int); +void rt_ifmsg(struct ifnet *); +void rt_missmsg(int, struct rt_addrinfo *, int, int); +void rt_missmsg_fib(int, struct rt_addrinfo *, int, int, int); +int rt_addrmsg(int, struct ifaddr *, int); +int rt_routemsg(int, struct rtentry *, struct nhop_object *, int); +int rt_routemsg_info(int, struct rt_addrinfo *, int); +void rt_newmaddrmsg(int, struct ifmultiaddr *); +void rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *); +struct rib_head *rt_table_init(int, int, u_int); +void rt_table_destroy(struct rib_head *); +u_int rt_tables_get_gen(uint32_t table, sa_family_t family); + +struct sockaddr *rtsock_fix_netmask(const struct sockaddr *dst, + const struct sockaddr *smask, struct sockaddr_storage *dmask); + +void rt_updatemtu(struct ifnet *); + +void rt_flushifroutes(struct ifnet *ifp); + +/* XXX MRT NEW VERSIONS THAT USE FIBs + * For now the protocol indepedent versions are the same as the AF_INET ones + * but this will change.. + */ +int rtioctl_fib(u_long, caddr_t, u_int); +int rib_lookup_info(uint32_t, const struct sockaddr *, uint32_t, uint32_t, + struct rt_addrinfo *); +void rib_free_info(struct rt_addrinfo *info); + +/* New API */ +void rib_flush_routes_family(int family); +struct nhop_object *rib_lookup(uint32_t fibnum, const struct sockaddr *dst, + uint32_t flags, uint32_t flowid); +#endif + #endif diff --git a/tools/compat/include/net/route/nhop.h b/tools/compat/include/net/route/nhop.h new file mode 100644 index 000000000..ce18cc04e --- /dev/null +++ b/tools/compat/include/net/route/nhop.h @@ -0,0 +1,245 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 Alexander V. Chernikov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * This header file contains public definitions for the nexthop routing subsystem. + */ + +#ifndef _NET_ROUTE_NHOP_H_ +#define _NET_ROUTE_NHOP_H_ + +#include /* sockaddr_in && sockaddr_in6 */ + +#include + +enum nhop_type { + NH_TYPE_IPV4_ETHER_RSLV = 1, /* IPv4 ethernet without GW */ + NH_TYPE_IPV4_ETHER_NHOP = 2, /* IPv4 with pre-calculated ethernet encap */ + NH_TYPE_IPV6_ETHER_RSLV = 3, /* IPv6 ethernet, without GW */ + NH_TYPE_IPV6_ETHER_NHOP = 4 /* IPv6 with pre-calculated ethernet encap*/ +}; + +#ifdef _KERNEL + +/* + * Define shorter version of AF_LINK sockaddr. + * + * Currently the only use case of AF_LINK gateway is storing + * interface index of the interface of the source IPv6 address. + * This is used by the IPv6 code for the connections over loopback + * interface. + * + * The structure below copies 'struct sockaddr_dl', reducing the + * size of sdl_data buffer, as it is not used. This change + * allows to store the AF_LINK gateways in the nhop gateway itself, + * simplifying control plane handling. + */ +struct sockaddr_dl_short { + u_char sdl_len; /* Total length of sockaddr */ + u_char sdl_family; /* AF_LINK */ + u_short sdl_index; /* if != 0, system given index for interface */ + u_char sdl_type; /* interface type */ + u_char sdl_nlen; /* interface name length, no trailing 0 reqd. */ + u_char sdl_alen; /* link level address length */ + u_char sdl_slen; /* link layer selector length */ + char sdl_data[8]; /* unused */ +}; + +#define NHOP_RELATED_FLAGS \ + (RTF_GATEWAY | RTF_HOST | RTF_REJECT | RTF_BLACKHOLE | \ + RTF_FIXEDMTU | RTF_LOCAL | RTF_BROADCAST | RTF_MULTICAST) + +struct nh_control; +struct nhop_priv; + +/* + * Struct 'nhop_object' field description: + * + * nh_flags: NHF_ flags used in the dataplane code. NHF_GATEWAY or NHF_BLACKHOLE + * can be examples of such flags. + * nh_mtu: ready-to-use nexthop mtu. Already accounts for the link-level header, + * interface MTU and protocol-specific limitations. + * nh_prepend_len: link-level prepend length. Currently unused. + * nh_ifp: logical transmit interface. The one from which if_transmit() will be + * called. Guaranteed to be non-NULL. + * nh_aifp: ifnet of the source address. Same as nh_ifp except IPv6 loopback + * routes. See the example below. + * nh_ifa: interface address to use. Guaranteed to be non-NULL. + * nh_pksent: counter(9) reflecting the number of packets transmitted. + * + * gw_: storage suitable to hold AF_INET, AF_INET6 or AF_LINK gateway. More + * details ara available in the examples below. + * + * Examples: + * + * Direct routes (routes w/o gateway): + * NHF_GATEWAY is NOT set. + * nh_ifp denotes the logical transmit interface (). + * nh_aifp is the same as nh_ifp + * gw_sa contains AF_LINK sa with nh_aifp ifindex (compat) + * Loopback routes: + * NHF_GATEWAY is NOT set. + * nh_ifp points to the loopback interface (lo0). + * nh_aifp points to the interface where the destination address belongs to. + * This is useful in IPv6 link-local-over-loopback communications. + * gw_sa contains AF_LINK sa with nh_aifp ifindex (compat) + * GW routes: + * NHF_GATEWAY is set. + * nh_ifp denotes the logical transmit interface. + * nh_aifp is the same as nh_ifp + * gw_sa contains L3 address (either AF_INET or AF_INET6). + * + * + * Note: struct nhop_object fields are ordered in a way that + * supports memcmp-based comparisons. + * + */ +#define NHOP_END_CMP (__offsetof(struct nhop_object, nh_pksent)) + +struct nhop_object { + uint16_t nh_flags; /* nhop flags */ + uint16_t nh_mtu; /* nexthop mtu */ + union { + struct sockaddr_in gw4_sa; /* GW accessor as IPv4 */ + struct sockaddr_in6 gw6_sa; /* GW accessor as IPv6 */ + struct sockaddr gw_sa; + struct sockaddr_dl_short gwl_sa; /* AF_LINK gw (compat) */ + char gw_buf[28]; + }; + struct ifnet *nh_ifp; /* Logical egress interface. Always != NULL */ + struct ifaddr *nh_ifa; /* interface address to use. Always != NULL */ + struct ifnet *nh_aifp; /* ifnet of the source address. Always != NULL */ + counter_u64_t nh_pksent; /* packets sent using this nhop */ + /* 32 bytes + 4xPTR == 64(amd64) / 48(i386) */ + uint8_t nh_prepend_len; /* length of prepend data */ + uint8_t spare[3]; + uint32_t spare1; /* alignment */ + char nh_prepend[48]; /* L2 prepend */ + struct nhop_priv *nh_priv; /* control plane data */ + /* -- 128 bytes -- */ +}; + +/* + * Nhop validness. + * + * Currently we verify whether link is up or not on every packet, which can be + * quite costy. + * TODO: subscribe for the interface notifications and update the nexthops + * with NHF_INVALID flag. + */ + +#define NH_IS_VALID(_nh) RT_LINK_IS_UP((_nh)->nh_ifp) +#define NH_IS_NHGRP(_nh) ((_nh)->nh_flags & NHF_MULTIPATH) + +#define NH_FREE(_nh) do { \ + nhop_free(_nh); \ + /* guard against invalid refs */ \ + _nh = NULL; \ +} while (0) + +struct weightened_nhop { + struct nhop_object *nh; + uint32_t weight; +}; + +void nhop_free(struct nhop_object *nh); + +struct sysctl_req; +struct sockaddr_dl; +struct rib_head; + +uint32_t nhop_get_idx(const struct nhop_object *nh); +enum nhop_type nhop_get_type(const struct nhop_object *nh); +int nhop_get_rtflags(const struct nhop_object *nh); +struct vnet *nhop_get_vnet(const struct nhop_object *nh); +struct nhop_object *nhop_select_func(struct nhop_object *nh, uint32_t flowid); + +#endif /* _KERNEL */ + +/* Kernel <> userland structures */ + +/* Structure usage and layout are described in dump_nhop_entry() */ +struct nhop_external { + uint32_t nh_len; /* length of the datastructure */ + uint32_t nh_idx; /* Nexthop index */ + uint32_t nh_fib; /* Fib nexhop is attached to */ + uint32_t ifindex; /* transmit interface ifindex */ + uint32_t aifindex; /* address ifindex */ + uint8_t prepend_len; /* length of the prepend */ + uint8_t nh_family; /* address family */ + uint16_t nh_type; /* nexthop type */ + uint16_t nh_mtu; /* nexthop mtu */ + + uint16_t nh_flags; /* nhop flags */ + struct in_addr nh_addr; /* GW/DST IPv4 address */ + struct in_addr nh_src; /* default source IPv4 address */ + uint64_t nh_pksent; + /* control plane */ + /* lookup key: address, family, type */ + char nh_prepend[64]; /* L2 prepend */ + uint64_t nh_refcount; /* number of references */ +}; + +struct nhop_addrs { + uint32_t na_len; /* length of the datastructure */ + uint16_t gw_sa_off; /* offset of gateway SA */ + uint16_t src_sa_off; /* offset of src address SA */ +}; + +#define NHG_C_TYPE_CNHOPS 0x1 /* Control plane nhops list */ +#define NHG_C_TYPE_DNHOPS 0x2 /* Dataplane nhops list */ +struct nhgrp_container { + uint32_t nhgc_len; /* container length */ + uint16_t nhgc_count; /* number of items */ + uint8_t nhgc_type; /* container type */ + uint8_t nhgc_subtype; /* container subtype */ +}; + +struct nhgrp_nhop_external { + uint32_t nh_idx; + uint32_t nh_weight; +}; + +/* + * Layout: + * - nhgrp_external + * - nhgrp_container (control plane nhops list) + * - nhgrp_nhop_external + * - nhgrp_nhop_external + * .. + * - nhgrp_container (dataplane nhops list) + * - nhgrp_nhop_external + * - nhgrp_nhop_external + */ +struct nhgrp_external { + uint32_t nhg_idx; /* Nexthop group index */ + uint32_t nhg_refcount; /* number of references */ +}; + +#endif diff --git a/tools/compat/include/netinet/icmp6.h b/tools/compat/include/netinet/icmp6.h index cd7a2afd9..19a02551c 100644 --- a/tools/compat/include/netinet/icmp6.h +++ b/tools/compat/include/netinet/icmp6.h @@ -2,6 +2,8 @@ /* $KAME: icmp6.h,v 1.46 2001/04/27 15:09:48 itojun Exp $ */ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * @@ -42,7 +44,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -246,6 +248,10 @@ struct nd_router_advert { /* router advertisement */ #define ND_RA_FLAG_RTPREF_LOW 0x18 /* 00011000 */ #define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */ +#ifdef EXPERIMENTAL +#define ND_RA_FLAG_IPV6_ONLY 0x02 /* draft-ietf-6man-ipv6only-flag */ +#endif + #define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1] struct nd_neighbor_solicit { /* neighbor solicitation */ @@ -342,7 +348,7 @@ struct nd_opt_mtu { /* MTU option */ #define ND_OPT_NONCE_LEN ((1 * 8) - 2) #if ((ND_OPT_NONCE_LEN + 2) % 8) != 0 #error "(ND_OPT_NONCE_LEN + 2) must be a multiple of 8." -#endif +#endif struct nd_opt_nonce { /* nonce option */ u_int8_t nd_opt_nonce_type; u_int8_t nd_opt_nonce_len; @@ -605,7 +611,7 @@ struct icmp6stat { * for netinet6 code, it is already available in icp6s_outhist[]. */ uint64_t icp6s_reflect; - uint64_t icp6s_inhist[256]; + uint64_t icp6s_inhist[256]; uint64_t icp6s_nd_toomanyopt; /* too many ND options */ struct icmp6errstat icp6s_outerrhist; #define icp6s_odst_unreach_noroute \ @@ -630,9 +636,15 @@ struct icmp6stat { uint64_t icp6s_nd_badopt; /* bad ND options */ uint64_t icp6s_badns; /* bad neighbor solicitation */ uint64_t icp6s_badna; /* bad neighbor advertisement */ - uint64_t icp6s_badrs; /* bad router advertisement */ + uint64_t icp6s_badrs; /* bad router solicitation */ uint64_t icp6s_badra; /* bad router advertisement */ uint64_t icp6s_badredirect; /* bad redirect message */ + uint64_t icp6s_overflowdefrtr; /* Too many default routers. */ + uint64_t icp6s_overflowprfx; /* Too many prefixes. */ + uint64_t icp6s_overflownndp; /* Too many neighbour entries. */ + uint64_t icp6s_overflowredirect;/* Too many redirects. */ + uint64_t icp6s_invlhlim; /* Invalid hop limit. */ + uint64_t icp6s_spare[32]; }; #ifdef _KERNEL @@ -685,11 +697,9 @@ void kmod_icmp6stat_inc(int statnum); #define ICMPV6CTL_NODEINFO_OLDMCPREFIX 25 #define ICMPV6CTL_MAXID 26 -#define RTF_PROBEMTU RTF_PROTO1 - #ifdef _KERNEL # ifdef __STDC__ -struct rtentry; +struct nhop_object; struct rttimer; struct in6_multi; # endif @@ -699,10 +709,9 @@ void icmp6_error2(struct mbuf *, int, int, int, struct ifnet *); int icmp6_input(struct mbuf **, int *, int); void icmp6_fasttimo(void); void icmp6_slowtimo(void); -void icmp6_reflect(struct mbuf *, size_t); void icmp6_prepare(struct mbuf *); void icmp6_redirect_input(struct mbuf *, int); -void icmp6_redirect_output(struct mbuf *, struct rtentry *); +void icmp6_redirect_output(struct mbuf *, struct nhop_object *); struct ip6ctlparam; void icmp6_mtudisc_update(struct ip6ctlparam *, int); diff --git a/tools/compat/include/netinet/icmp_var.h b/tools/compat/include/netinet/icmp_var.h index d3e72bc28..c1ed83e54 100644 --- a/tools/compat/include/netinet/icmp_var.h +++ b/tools/compat/include/netinet/icmp_var.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -33,7 +35,6 @@ #ifndef _NETINET_ICMP_VAR_H_ #define _NETINET_ICMP_VAR_H_ - /* * Variables related to this implementation * of the internet control message protocol. @@ -96,7 +97,7 @@ extern int badport_bandlim(int); #define BANDLIM_RST_OPENPORT 4 /* No connection, listener */ #define BANDLIM_ICMP6_UNREACH 5 #define BANDLIM_SCTP_OOTB 6 -#define BANDLIM_MAX 6 +#define BANDLIM_MAX 7 #endif #endif diff --git a/tools/compat/include/netinet/if_ether.h b/tools/compat/include/netinet/if_ether.h index aed1e67ee..2f56e7a91 100644 --- a/tools/compat/include/netinet/if_ether.h +++ b/tools/compat/include/netinet/if_ether.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -108,4 +110,20 @@ struct sockaddr_inarp { #define RTF_USETRAILERS RTF_PROTO1 /* use trailers */ #define RTF_ANNOUNCE RTF_PROTO2 /* announce new arp entry */ +#ifdef _KERNEL +extern u_char ether_ipmulticast_min[ETHER_ADDR_LEN]; +extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN]; + +struct ifaddr; +struct llentry; + +int arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m, + const struct sockaddr *dst, u_char *desten, uint32_t *pflags, + struct llentry **plle); +void arprequest(struct ifnet *, const struct in_addr *, + const struct in_addr *, u_char *); +void arp_ifinit(struct ifnet *, struct ifaddr *); +void arp_announce_ifaddr(struct ifnet *, struct in_addr addr, u_char *); +#endif + #endif diff --git a/tools/compat/include/netinet/igmp.h b/tools/compat/include/netinet/igmp.h index 8f574290b..873d6419b 100644 --- a/tools/compat/include/netinet/igmp.h +++ b/tools/compat/include/netinet/igmp.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1988 Stephen Deering. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -14,7 +16,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/tools/compat/include/netinet/igmp_var.h b/tools/compat/include/netinet/igmp_var.h index 5242d07d1..16532987f 100644 --- a/tools/compat/include/netinet/igmp_var.h +++ b/tools/compat/include/netinet/igmp_var.h @@ -1,4 +1,6 @@ -/*-a +/*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1988 Stephen Deering. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -14,7 +16,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -52,6 +54,7 @@ struct igmpstat { /* * Structure header (to insulate ABI changes). + * XXX: unset inside the kernel, exported via sysctl_igmp_stat(). */ uint32_t igps_version; /* version of this structure */ uint32_t igps_len; /* length of this structure */ @@ -182,8 +185,12 @@ struct igmp_ifinfo { }; #ifdef _KERNEL -#define IGMPSTAT_ADD(name, val) V_igmpstat.name += (val) -#define IGMPSTAT_INC(name) IGMPSTAT_ADD(name, 1) +#include + +VNET_PCPUSTAT_DECLARE(struct igmpstat, igmpstat); +#define IGMPSTAT_ADD(name, val) \ + VNET_PCPUSTAT_ADD(struct igmpstat, igmpstat, name, (val)) +#define IGMPSTAT_INC(name) IGMPSTAT_ADD(name, 1) /* * Subsystem lock macros. @@ -212,7 +219,6 @@ struct igmp_ifsoftc { uint32_t igi_qi; /* IGMPv3 Query Interval (s) */ uint32_t igi_qri; /* IGMPv3 Query Response Interval (s) */ uint32_t igi_uri; /* IGMPv3 Unsolicited Report Interval (s) */ - SLIST_HEAD(,in_multi) igi_relinmhead; /* released groups */ struct mbufq igi_gq; /* general query responses queue */ }; diff --git a/tools/compat/include/netinet/in.h b/tools/compat/include/netinet/in.h index 88e0c2369..cb2a9dbcd 100644 --- a/tools/compat/include/netinet/in.h +++ b/tools/compat/include/netinet/in.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -100,11 +102,11 @@ struct sockaddr_in { }; #ifndef _BYTEORDER_PROTOTYPED -#define _BYTEORDER_PROTOTYPED -extern uint32_t htonl(uint32_t); -extern uint16_t htons(uint16_t); -extern uint32_t ntohl(uint32_t); -extern uint16_t ntohs(uint16_t); +#define _BYTEORDER_PROTOTYPED +extern uint32_t htonl(uint32_t); +extern uint16_t htons(uint16_t); +extern uint32_t ntohl(uint32_t); +extern uint16_t ntohs(uint16_t); #endif #define IPPROTO_IPV6 41 /* IP6 header */ @@ -150,7 +152,7 @@ extern uint16_t ntohs(uint16_t); #define IPPROTO_BLT 30 /* Bulk Data Transfer */ #define IPPROTO_NSP 31 /* Network Services */ #define IPPROTO_INP 32 /* Merit Internodal */ -#define IPPROTO_SEP 33 /* Sequential Exchange */ +#define IPPROTO_DCCP 33 /* Datagram Congestion Control Protocol */ #define IPPROTO_3PC 34 /* Third Party Connect */ #define IPPROTO_IDPR 35 /* InterDomain Policy Routing */ #define IPPROTO_XTP 36 /* XTP */ @@ -272,7 +274,7 @@ extern uint16_t ntohs(uint16_t); * if you trust the remote host to restrict these ports. * * The default range of ports and the high range can be changed by - * sysctl(3). (net.inet.ip.port{hi,low}{first,last}_auto) + * sysctl(3). (net.inet.ip.portrange.{hi,low,}{first,last}) * * Changing those values has bad security implications if you are * using a stateless firewall that is allowing packets outside of that @@ -304,8 +306,8 @@ extern uint16_t ntohs(uint16_t); * Default local port range, used by IP_PORTRANGE_DEFAULT */ #define IPPORT_EPHEMERALFIRST 10000 -#define IPPORT_EPHEMERALLAST 65535 - +#define IPPORT_EPHEMERALLAST 65535 + /* * Dynamic port range, used by IP_PORTRANGE_HIGH. */ @@ -362,7 +364,7 @@ extern uint16_t ntohs(uint16_t); (((in_addr_t)(i) & 0xffff0000) == 0xc0a80000)) #define IN_LOCAL_GROUP(i) (((in_addr_t)(i) & 0xffffff00) == 0xe0000000) - + #define IN_ANY_LOCAL(i) (IN_LINKLOCAL(i) || IN_LOCAL_GROUP(i)) #define INADDR_LOOPBACK ((in_addr_t)0x7f000001) @@ -416,6 +418,8 @@ extern uint16_t ntohs(uint16_t); #define IP_BINDANY 24 /* bool: allow bind to any address */ #define IP_BINDMULTI 25 /* bool: allow multiple listeners on a tuple */ #define IP_RSS_LISTEN_BUCKET 26 /* int; set RSS listen bucket */ +#define IP_ORIGDSTADDR 27 /* bool: receive IP dst addr/port w/dgram */ +#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR /* * Options for controlling the firewall and dummynet. @@ -462,6 +466,10 @@ extern uint16_t ntohs(uint16_t); /* The following option is private; do not use it from user applications. */ #define IP_MSFILTER 74 /* set/get filter list */ +/* The following option deals with the 802.1Q Ethernet Priority Code Point */ +#define IP_VLAN_PCP 75 /* int; set/get PCP used for packet, */ + /* -1 use interface default */ + /* Protocol Independent Multicast API [RFC3678] */ #define MCAST_JOIN_GROUP 80 /* join an any-source group */ #define MCAST_LEAVE_GROUP 81 /* leave all sources for group */ @@ -484,13 +492,9 @@ extern uint16_t ntohs(uint16_t); #define IP_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */ /* - * The imo_membership vector for each socket is now dynamically allocated at - * run-time, bounded by USHRT_MAX, and is reallocated when needed, sized - * according to a power-of-two increment. + * Limit for IPv4 multicast memberships */ -#define IP_MIN_MEMBERSHIPS 31 #define IP_MAX_MEMBERSHIPS 4095 -#define IP_MAX_SOURCE_FILTER 1024 /* XXX to be unused */ /* * Default resource limits for IPv4 multicast source filtering. @@ -598,6 +602,8 @@ struct __msfilterreq { #define IPCTL_FASTFORWARDING 14 /* use fast IP forwarding code */ /* 15, unused, was: IPCTL_KEEPFAITH */ #define IPCTL_GIF_TTL 16 /* default TTL for gif encap packet */ +#define IPCTL_INTRDQMAXLEN 17 /* max length of direct netisr queue */ +#define IPCTL_INTRDQDROPS 18 /* number of direct netisr q drops */ #endif /* __BSD_VISIBLE */ diff --git a/tools/compat/include/netinet/in_pcb.h b/tools/compat/include/netinet/in_pcb.h index 4e3fbe559..439a0c06f 100644 --- a/tools/compat/include/netinet/in_pcb.h +++ b/tools/compat/include/netinet/in_pcb.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1990, 1993 * The Regents of the University of California. * Copyright (c) 2010-2011 Juniper Networks, Inc. @@ -15,7 +17,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -39,6 +41,7 @@ #define _NETINET_IN_PCB_H_ #include +#include #include #include #include @@ -50,10 +53,7 @@ #include #include #endif - -#define in6pcb inpcb /* for KAME src sync over BSD*'s */ -#define in6p_sp inp_sp /* for KAME src sync over BSD*'s */ -struct inpcbpolicy; +#include /* * struct inpcb is the common protocol control block structure used in most @@ -63,9 +63,10 @@ struct inpcbpolicy; * numbers, and pointers up (to a socket structure) and down (to a * protocol-specific control block) are stored here. */ -LIST_HEAD(inpcbhead, inpcb); -LIST_HEAD(inpcbporthead, inpcbport); -typedef u_quad_t inp_gen_t; +CK_LIST_HEAD(inpcbhead, inpcb); +CK_LIST_HEAD(inpcbporthead, inpcbport); +CK_LIST_HEAD(inpcblbgrouphead, inpcblbgroup); +typedef uint64_t inp_gen_t; /* * PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet. @@ -77,6 +78,11 @@ struct in_addr_4in6 { struct in_addr ia46_addr4; }; +union in_dependaddr { + struct in_addr_4in6 id46_addr; + struct in6_addr id6_addr; +}; + /* * NOTE: ipv6 addrs should be 64-bit aligned, per RFC 2553. in_conninfo has * some extra padding to accomplish this. @@ -87,22 +93,14 @@ struct in_endpoints { u_int16_t ie_fport; /* foreign port */ u_int16_t ie_lport; /* local port */ /* protocol dependent part, local and foreign addr */ - union { - /* foreign host table entry */ - struct in_addr_4in6 ie46_foreign; - struct in6_addr ie6_foreign; - } ie_dependfaddr; - union { - /* local host table entry */ - struct in_addr_4in6 ie46_local; - struct in6_addr ie6_local; - } ie_dependladdr; + union in_dependaddr ie_dependfaddr; /* foreign host table entry */ + union in_dependaddr ie_dependladdr; /* local host table entry */ +#define ie_faddr ie_dependfaddr.id46_addr.ia46_addr4 +#define ie_laddr ie_dependladdr.id46_addr.ia46_addr4 +#define ie6_faddr ie_dependfaddr.id6_addr +#define ie6_laddr ie_dependladdr.id6_addr u_int32_t ie6_zoneid; /* scope zone id */ }; -#define ie_faddr ie_dependfaddr.ie46_foreign.ia46_addr4 -#define ie_laddr ie_dependladdr.ie46_local.ia46_addr4 -#define ie6_faddr ie_dependfaddr.ie6_foreign -#define ie6_laddr ie_dependladdr.ie6_local /* * XXX The defines for inc_* are hacks and should be changed to direct @@ -120,8 +118,8 @@ struct in_conninfo { * Flags for inc_flags. */ #define INC_ISIPV6 0x01 +#define INC_IPV6MINMTU 0x02 -#define inc_isipv6 inc_flags /* temp compatibility */ #define inc_fport inc_ie.ie_fport #define inc_lport inc_ie.ie_lport #define inc_faddr inc_ie.ie_faddr @@ -130,9 +128,8 @@ struct in_conninfo { #define inc6_laddr inc_ie.ie6_laddr #define inc6_zoneid inc_ie.ie6_zoneid -struct icmp6_filter; - -/*- +#if defined(_KERNEL) || defined(_WANT_INPCB) +/* * struct inpcb captures the network layer state for TCP, UDP, and raw IPv4 and * IPv6 sockets. In the case of TCP and UDP, further per-connection state is * hung off of inp_ppcb most of the time. Almost all fields of struct inpcb @@ -156,7 +153,9 @@ struct icmp6_filter; * from the global list. * * Key: + * (b) - Protected by the hpts lock. * (c) - Constant after initialization + * (e) - Protected by the net_epoch_prempt epoch * (g) - Protected by the pcbgroup lock * (i) - Protected by the inpcb lock * (p) - Protected by the pcbinfo lock for the inpcb @@ -165,6 +164,51 @@ struct icmp6_filter; * (s) - Protected by another subsystem's locks * (x) - Undefined locking * + * Notes on the tcp_hpts: + * + * First Hpts lock order is + * 1) INP_WLOCK() + * 2) HPTS_LOCK() i.e. hpts->pmtx + * + * To insert a TCB on the hpts you *must* be holding the INP_WLOCK(). + * You may check the inp->inp_in_hpts flag without the hpts lock. + * The hpts is the only one that will clear this flag holding + * only the hpts lock. This means that in your tcp_output() + * routine when you test for the inp_in_hpts flag to be 1 + * it may be transitioning to 0 (by the hpts). + * That's ok since that will just mean an extra call to tcp_output + * that most likely will find the call you executed + * (when the mis-match occured) will have put the TCB back + * on the hpts and it will return. If your + * call did not add the inp back to the hpts then you will either + * over-send or the cwnd will block you from sending more. + * + * Note you should also be holding the INP_WLOCK() when you + * call the remove from the hpts as well. Though usually + * you are either doing this from a timer, where you need and have + * the INP_WLOCK() or from destroying your TCB where again + * you should already have the INP_WLOCK(). + * + * The inp_hpts_cpu, inp_hpts_cpu_set, inp_input_cpu and + * inp_input_cpu_set fields are controlled completely by + * the hpts. Do not ever set these. The inp_hpts_cpu_set + * and inp_input_cpu_set fields indicate if the hpts has + * setup the respective cpu field. It is advised if this + * field is 0, to enqueue the packet with the appropriate + * hpts_immediate() call. If the _set field is 1, then + * you may compare the inp_*_cpu field to the curcpu and + * may want to again insert onto the hpts if these fields + * are not equal (i.e. you are not on the expected CPU). + * + * A note on inp_hpts_calls and inp_input_calls, these + * flags are set when the hpts calls either the output + * or do_segment routines respectively. If the routine + * being called wants to use this, then it needs to + * clear the flag before returning. The hpts will not + * clear the flag. The flags can be used to tell if + * the hpts is the function calling the respective + * routine. + * * A few other notes: * * When a read lock is held, stability of the field is guaranteed; to write @@ -181,32 +225,67 @@ struct icmp6_filter; * read-lock usage during modification, this model can be applied to other * protocols (especially SCTP). */ +struct icmp6_filter; +struct inpcbpolicy; +struct m_snd_tag; struct inpcb { - LIST_ENTRY(inpcb) inp_hash; /* (h/i) hash list */ - LIST_ENTRY(inpcb) inp_pcbgrouphash; /* (g/i) hash list */ - LIST_ENTRY(inpcb) inp_list; /* (p/l) list for all PCBs for proto */ - /* (p[w]) for list iteration */ - /* (p[r]/l) for addition/removal */ - void *inp_ppcb; /* (i) pointer to per-protocol pcb */ - struct inpcbinfo *inp_pcbinfo; /* (c) PCB list info */ - struct inpcbgroup *inp_pcbgroup; /* (g/i) PCB group list */ - LIST_ENTRY(inpcb) inp_pcbgroup_wild; /* (g/i/h) group wildcard entry */ - struct socket *inp_socket; /* (i) back pointer to socket */ - struct ucred *inp_cred; /* (c) cache of socket cred */ - u_int32_t inp_flow; /* (i) IPv6 flow information */ + /* Cache line #1 (amd64) */ + CK_LIST_ENTRY(inpcb) inp_hash; /* [w](h/i) [r](e/i) hash list */ + CK_LIST_ENTRY(inpcb) inp_pcbgrouphash; /* (g/i) hash list */ + struct rwlock inp_lock; + /* Cache line #2 (amd64) */ +#define inp_start_zero inp_hpts +#define inp_zero_size (sizeof(struct inpcb) - \ + offsetof(struct inpcb, inp_start_zero)) + TAILQ_ENTRY(inpcb) inp_hpts; /* pacing out queue next lock(b) */ + + uint32_t inp_hpts_request; /* Current hpts request, zero if + * fits in the pacing window (i&b). */ + /* + * Note the next fields are protected by a + * different lock (hpts-lock). This means that + * they must correspond in size to the smallest + * protectable bit field (uint8_t on x86, and + * other platfomrs potentially uint32_t?). Also + * since CPU switches can occur at different times the two + * fields can *not* be collapsed into a signal bit field. + */ +#if defined(__amd64__) || defined(__i386__) + volatile uint8_t inp_in_hpts; /* on output hpts (lock b) */ + volatile uint8_t inp_in_input; /* on input hpts (lock b) */ +#else + volatile uint32_t inp_in_hpts; /* on output hpts (lock b) */ + volatile uint32_t inp_in_input; /* on input hpts (lock b) */ +#endif + volatile uint16_t inp_hpts_cpu; /* Lock (i) */ + u_int inp_refcount; /* (i) refcount */ int inp_flags; /* (i) generic IP/datagram flags */ int inp_flags2; /* (i) generic IP/datagram flags #2*/ + volatile uint16_t inp_input_cpu; /* Lock (i) */ + volatile uint8_t inp_hpts_cpu_set :1, /* on output hpts (i) */ + inp_input_cpu_set : 1, /* on input hpts (i) */ + inp_hpts_calls :1, /* (i) from output hpts */ + inp_input_calls :1, /* (i) from input hpts */ + inp_spare_bits2 : 4; + uint8_t inp_numa_domain; /* numa domain */ + void *inp_ppcb; /* (i) pointer to per-protocol pcb */ + struct socket *inp_socket; /* (i) back pointer to socket */ + uint32_t inp_hptsslot; /* Hpts wheel slot this tcb is Lock(i&b) */ + uint32_t inp_hpts_drop_reas; /* reason we are dropping the PCB (lock i&b) */ + TAILQ_ENTRY(inpcb) inp_input; /* pacing in queue next lock(b) */ + struct inpcbinfo *inp_pcbinfo; /* (c) PCB list info */ + struct inpcbgroup *inp_pcbgroup; /* (g/i) PCB group list */ + CK_LIST_ENTRY(inpcb) inp_pcbgroup_wild; /* (g/i/h) group wildcard entry */ + struct ucred *inp_cred; /* (c) cache of socket cred */ + u_int32_t inp_flow; /* (i) IPv6 flow information */ u_char inp_vflag; /* (i) IP version flag (v4/v6) */ u_char inp_ip_ttl; /* (i) time to live proto */ u_char inp_ip_p; /* (c) protocol proto */ u_char inp_ip_minttl; /* (i) minimum TTL or drop */ uint32_t inp_flowid; /* (x) flow id / queue id */ - u_int inp_refcount; /* (i) refcount */ - void *inp_pspare[5]; /* (x) packet pacing / general use */ + struct m_snd_tag *inp_snd_tag; /* (i) send tag for outgoing mbufs */ uint32_t inp_flowtype; /* (x) M_HASHTYPE value */ uint32_t inp_rss_listen_bucket; /* (x) overridden RSS listen bucket */ - u_int inp_ispare[4]; /* (x) packet pacing / user cookie / - * general use */ /* Local and foreign ports, local and foreign addr. */ struct in_conninfo inp_inc; /* (i) list for PCB's local port */ @@ -217,55 +296,47 @@ struct inpcb { /* Protocol-dependent part; options. */ struct { - u_char inp4_ip_tos; /* (i) type of service proto */ - struct mbuf *inp4_options; /* (i) IP options */ - struct ip_moptions *inp4_moptions; /* (i) IP mcast options */ - } inp_depend4; + u_char inp_ip_tos; /* (i) type of service proto */ + struct mbuf *inp_options; /* (i) IP options */ + struct ip_moptions *inp_moptions; /* (i) mcast options */ + }; struct { /* (i) IP options */ - struct mbuf *inp6_options; + struct mbuf *in6p_options; /* (i) IP6 options for outgoing packets */ - struct ip6_pktopts *inp6_outputopts; + struct ip6_pktopts *in6p_outputopts; /* (i) IP multicast options */ - struct ip6_moptions *inp6_moptions; + struct ip6_moptions *in6p_moptions; /* (i) ICMPv6 code type filter */ - struct icmp6_filter *inp6_icmp6filt; + struct icmp6_filter *in6p_icmp6filt; /* (i) IPV6_CHECKSUM setsockopt */ - int inp6_cksum; - short inp6_hops; - } inp_depend6; - LIST_ENTRY(inpcb) inp_portlist; /* (i/h) */ + int in6p_cksum; + short in6p_hops; + }; + CK_LIST_ENTRY(inpcb) inp_portlist; /* (i/h) */ struct inpcbport *inp_phd; /* (i/h) head of this list */ -#define inp_zero_size offsetof(struct inpcb, inp_gencnt) inp_gen_t inp_gencnt; /* (c) generation count */ - struct llentry *inp_lle; /* cached L2 information */ - struct rwlock inp_lock; + void *spare_ptr; /* Spare pointer. */ rt_gen_t inp_rt_cookie; /* generation for route entry */ union { /* cached L3 information */ - struct route inpu_route; - struct route_in6 inpu_route6; - } inp_rtu; -#define inp_route inp_rtu.inpu_route -#define inp_route6 inp_rtu.inpu_route6 + struct route inp_route; + struct route_in6 inp_route6; + }; + CK_LIST_ENTRY(inpcb) inp_list; /* (p/l) list for all PCBs for proto */ + /* (e[r]) for list iteration */ + /* (p[w]/l) for addition/removal */ + struct epoch_context inp_epoch_ctx; }; +#endif /* _KERNEL */ + #define inp_fport inp_inc.inc_fport #define inp_lport inp_inc.inc_lport #define inp_faddr inp_inc.inc_faddr #define inp_laddr inp_inc.inc_laddr -#define inp_ip_tos inp_depend4.inp4_ip_tos -#define inp_options inp_depend4.inp4_options -#define inp_moptions inp_depend4.inp4_moptions #define in6p_faddr inp_inc.inc6_faddr #define in6p_laddr inp_inc.inc6_laddr #define in6p_zoneid inp_inc.inc6_zoneid -#define in6p_hops inp_depend6.inp6_hops /* default hop limit */ -#define in6p_flowinfo inp_flow -#define in6p_options inp_depend6.inp6_options -#define in6p_outputopts inp_depend6.inp6_outputopts -#define in6p_moptions inp_depend6.inp6_moptions -#define in6p_icmp6filt inp_depend6.inp6_icmp6filt -#define in6p_cksum inp_depend6.inp6_cksum #define inp_vnet inp_pcbinfo->ipi_vnet @@ -279,29 +350,68 @@ struct inpcb { /* * Interface exported to userland by various protocols which use inpcbs. Hack * alert -- only define if struct xsocket is in scope. + * Fields prefixed with "xi_" are unique to this structure, and the rest + * match fields in the struct inpcb, to ease coding and porting. + * + * Legend: + * (s) - used by userland utilities in src + * (p) - used by utilities in ports + * (3) - is known to be used by third party software not in ports + * (n) - no known usage */ #ifdef _SYS_SOCKETVAR_H_ -struct xinpcb { - size_t xi_len; /* length of this structure */ - struct inpcb xi_inp; - struct xsocket xi_socket; - u_quad_t xi_alignment_hack; -}; +struct xinpcb { + ksize_t xi_len; /* length of this structure */ + struct xsocket xi_socket; /* (s,p) */ + struct in_conninfo inp_inc; /* (s,p) */ + uint64_t inp_gencnt; /* (s,p) */ + kvaddr_t inp_ppcb; /* (s) netstat(1) */ + int64_t inp_spare64[4]; + uint32_t inp_flow; /* (s) */ + uint32_t inp_flowid; /* (s) */ + uint32_t inp_flowtype; /* (s) */ + int32_t inp_flags; /* (s,p) */ + int32_t inp_flags2; /* (s) */ + int32_t inp_rss_listen_bucket; /* (n) */ + int32_t in6p_cksum; /* (n) */ + int32_t inp_spare32[4]; + uint16_t in6p_hops; /* (n) */ + uint8_t inp_ip_tos; /* (n) */ + int8_t pad8; + uint8_t inp_vflag; /* (s,p) */ + uint8_t inp_ip_ttl; /* (n) */ + uint8_t inp_ip_p; /* (n) */ + uint8_t inp_ip_minttl; /* (n) */ + int8_t inp_spare8[4]; +} __attribute__((__aligned__(8))); -struct xinpgen { - size_t xig_len; /* length of this structure */ - u_int xig_count; /* number of PCBs at this time */ - inp_gen_t xig_gen; /* generation count at this time */ - so_gen_t xig_sogen; /* socket generation count at this time */ -}; +struct xinpgen { + ksize_t xig_len; /* length of this structure */ + u_int xig_count; /* number of PCBs at this time */ + uint32_t _xig_spare32; + inp_gen_t xig_gen; /* generation count at this time */ + so_gen_t xig_sogen; /* socket generation count this time */ + uint64_t _xig_spare64[4]; +} __attribute__((__aligned__(8))); +#ifdef _KERNEL +void in_pcbtoxinpcb(const struct inpcb *, struct xinpcb *); +#endif #endif /* _SYS_SOCKETVAR_H_ */ struct inpcbport { - LIST_ENTRY(inpcbport) phd_hash; + struct epoch_context phd_epoch_ctx; + CK_LIST_ENTRY(inpcbport) phd_hash; struct inpcbhead phd_pcblist; u_short phd_port; }; +struct in_pcblist { + int il_count; + struct epoch_context il_epoch_ctx; + struct inpcbinfo *il_pcbinfo; + struct inpcb *il_inp_list[0]; +}; + /*- * Global data structure for each high-level protocol (UDP, TCP, ...) in both * IPv4 and IPv6. Holds inpcb lists and information for managing them. @@ -323,22 +433,23 @@ struct inpcbport { * Locking key: * * (c) Constant or nearly constant after initialisation + * (e) - Protected by the net_epoch_prempt epoch * (g) Locked by ipi_lock * (l) Locked by ipi_list_lock - * (h) Read using either ipi_hash_lock or inpcb lock; write requires both + * (h) Read using either net_epoch_preempt or inpcb lock; write requires both ipi_hash_lock and inpcb lock * (p) Protected by one or more pcbgroup locks * (x) Synchronisation properties poorly defined */ struct inpcbinfo { /* - * Global lock protecting full inpcb list traversal + * Global lock protecting inpcb list modification */ - struct rwlock ipi_lock; + struct mtx ipi_lock; /* * Global list of inpcbs on the protocol. */ - struct inpcbhead *ipi_listhead; /* (g/l) */ + struct inpcbhead *ipi_listhead; /* [r](e) [w](g/l) */ u_int ipi_count; /* (l) */ /* @@ -369,9 +480,9 @@ struct inpcbinfo { u_int ipi_hashfields; /* (c) */ /* - * Global lock protecting non-pcbgroup hash lookup tables. + * Global lock protecting modification non-pcbgroup hash lookup tables. */ - struct rwlock ipi_hash_lock; + struct mtx ipi_hash_lock; /* * Global hash of inpcbs, hashed by local and foreign addresses and @@ -394,6 +505,13 @@ struct inpcbinfo { struct inpcbhead *ipi_wildbase; /* (p) */ u_long ipi_wildmask; /* (p) */ + /* + * Load balance groups used for the SO_REUSEPORT_LB option, + * hashed by local port. + */ + struct inpcblbgrouphead *ipi_lbgrouphashbase; /* (h) */ + u_long ipi_lbgrouphashmask; /* (h) */ + /* * Pointer to network stack instance */ @@ -434,7 +552,28 @@ struct inpcbgroup { * wildcard list in inpcbinfo. */ struct mtx ipg_lock; -} __aligned(CACHE_LINE_SIZE); +} __attribute__((__aligned__(CACHE_LINE_SIZE))); + +/* + * Load balance groups used for the SO_REUSEPORT_LB socket option. Each group + * (or unique address:port combination) can be re-used at most + * INPCBLBGROUP_SIZMAX (256) times. The inpcbs are stored in il_inp which + * is dynamically resized as processes bind/unbind to that specific group. + */ +struct inpcblbgroup { + CK_LIST_ENTRY(inpcblbgroup) il_list; + struct epoch_context il_epoch_ctx; + uint16_t il_lport; /* (c) */ + u_char il_vflag; /* (c) */ + u_int8_t il_numa_domain; + uint32_t il_pad2; + union in_dependaddr il_dependladdr; /* (c) */ +#define il_laddr il_dependladdr.id46_addr.ia46_addr4 +#define il6_laddr il_dependladdr.id6_addr + uint32_t il_inpsiz; /* max count in il_inp[] (h) */ + uint32_t il_inpcnt; /* cur count in il_inp[] (h) */ + struct inpcb *il_inp[]; /* (h) */ +}; #define INP_LOCK_INIT(inp, d, t) \ rw_init_flags(&(inp)->inp_lock, (t), RW_RECURSE | RW_DUPOK) @@ -445,6 +584,7 @@ struct inpcbgroup { #define INP_TRY_WLOCK(inp) rw_try_wlock(&(inp)->inp_lock) #define INP_RUNLOCK(inp) rw_runlock(&(inp)->inp_lock) #define INP_WUNLOCK(inp) rw_wunlock(&(inp)->inp_lock) +#define INP_UNLOCK(inp) rw_unlock(&(inp)->inp_lock) #define INP_TRY_UPGRADE(inp) rw_try_upgrade(&(inp)->inp_lock) #define INP_DOWNGRADE(inp) rw_downgrade(&(inp)->inp_lock) #define INP_WLOCKED(inp) rw_wowned(&(inp)->inp_lock) @@ -463,20 +603,12 @@ void inp_wunlock(struct inpcb *); void inp_rlock(struct inpcb *); void inp_runlock(struct inpcb *); -#ifdef INVARIANTS +#ifdef INVARIANT_SUPPORT void inp_lock_assert(struct inpcb *); void inp_unlock_assert(struct inpcb *); #else -static __inline void -inp_lock_assert(struct inpcb *inp __unused) -{ -} - -static __inline void -inp_unlock_assert(struct inpcb *inp __unused) -{ -} - +#define inp_lock_assert(inp) do {} while (0) +#define inp_unlock_assert(inp) do {} while (0) #endif void inp_apply_all(void (*func)(struct inpcb *, void *), void *arg); @@ -488,25 +620,21 @@ struct tcpcb * inp_inpcbtotcpcb(struct inpcb *inp); void inp_4tuple_get(struct inpcb *inp, uint32_t *laddr, uint16_t *lp, uint32_t *faddr, uint16_t *fp); -short inp_so_options(const struct inpcb *inp); +int inp_so_options(const struct inpcb *inp); #endif /* _KERNEL */ #define INP_INFO_LOCK_INIT(ipi, d) \ - rw_init_flags(&(ipi)->ipi_lock, (d), RW_RECURSE) -#define INP_INFO_LOCK_DESTROY(ipi) rw_destroy(&(ipi)->ipi_lock) -#define INP_INFO_RLOCK(ipi) rw_rlock(&(ipi)->ipi_lock) -#define INP_INFO_WLOCK(ipi) rw_wlock(&(ipi)->ipi_lock) -#define INP_INFO_TRY_RLOCK(ipi) rw_try_rlock(&(ipi)->ipi_lock) -#define INP_INFO_TRY_WLOCK(ipi) rw_try_wlock(&(ipi)->ipi_lock) -#define INP_INFO_TRY_UPGRADE(ipi) rw_try_upgrade(&(ipi)->ipi_lock) -#define INP_INFO_WLOCKED(ipi) rw_wowned(&(ipi)->ipi_lock) -#define INP_INFO_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_lock) -#define INP_INFO_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_lock) -#define INP_INFO_LOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_LOCKED) -#define INP_INFO_RLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_RLOCKED) -#define INP_INFO_WLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_WLOCKED) -#define INP_INFO_UNLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_UNLOCKED) + mtx_init(&(ipi)->ipi_lock, (d), NULL, MTX_DEF| MTX_RECURSE) +#define INP_INFO_LOCK_DESTROY(ipi) mtx_destroy(&(ipi)->ipi_lock) +#define INP_INFO_WLOCK(ipi) mtx_lock(&(ipi)->ipi_lock) +#define INP_INFO_TRY_WLOCK(ipi) mtx_trylock(&(ipi)->ipi_lock) +#define INP_INFO_WLOCKED(ipi) mtx_owned(&(ipi)->ipi_lock) +#define INP_INFO_WUNLOCK(ipi) mtx_unlock(&(ipi)->ipi_lock) +#define INP_INFO_LOCK_ASSERT(ipi) MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(ipi)->ipi_lock)) +#define INP_INFO_WLOCK_ASSERT(ipi) mtx_assert(&(ipi)->ipi_lock, MA_OWNED) +#define INP_INFO_WUNLOCK_ASSERT(ipi) \ + mtx_assert(&(ipi)->ipi_lock, MA_NOTOWNED) #define INP_LIST_LOCK_INIT(ipi, d) \ rw_init_flags(&(ipi)->ipi_list_lock, (d), 0) @@ -527,17 +655,12 @@ short inp_so_options(const struct inpcb *inp); #define INP_LIST_UNLOCK_ASSERT(ipi) \ rw_assert(&(ipi)->ipi_list_lock, RA_UNLOCKED) -#define INP_HASH_LOCK_INIT(ipi, d) \ - rw_init_flags(&(ipi)->ipi_hash_lock, (d), 0) -#define INP_HASH_LOCK_DESTROY(ipi) rw_destroy(&(ipi)->ipi_hash_lock) -#define INP_HASH_RLOCK(ipi) rw_rlock(&(ipi)->ipi_hash_lock) -#define INP_HASH_WLOCK(ipi) rw_wlock(&(ipi)->ipi_hash_lock) -#define INP_HASH_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_hash_lock) -#define INP_HASH_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_hash_lock) -#define INP_HASH_LOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_hash_lock, \ - RA_LOCKED) -#define INP_HASH_WLOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_hash_lock, \ - RA_WLOCKED) +#define INP_HASH_LOCK_INIT(ipi, d) mtx_init(&(ipi)->ipi_hash_lock, (d), NULL, MTX_DEF) +#define INP_HASH_LOCK_DESTROY(ipi) mtx_destroy(&(ipi)->ipi_hash_lock) +#define INP_HASH_WLOCK(ipi) mtx_lock(&(ipi)->ipi_hash_lock) +#define INP_HASH_WUNLOCK(ipi) mtx_unlock(&(ipi)->ipi_hash_lock) +#define INP_HASH_LOCK_ASSERT(ipi) MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(ipi)->ipi_hash_lock)) +#define INP_HASH_WLOCK_ASSERT(ipi) mtx_assert(&(ipi)->ipi_hash_lock, MA_OWNED); #define INP_GROUP_LOCK_INIT(ipg, d) mtx_init(&(ipg)->ipg_lock, (d), NULL, \ MTX_DEF | MTX_DUPOK) @@ -551,6 +674,8 @@ short inp_so_options(const struct inpcb *inp); (((faddr) ^ ((faddr) >> 16) ^ ntohs((lport) ^ (fport))) & (mask)) #define INP_PCBPORTHASH(lport, mask) \ (ntohs((lport)) & (mask)) +#define INP_PCBLBGROUP_PKTHASH(faddr, lport, fport) \ + ((faddr) ^ ((faddr) >> 16) ^ ntohs((lport) ^ (fport))) #define INP6_PCBHASHKEY(faddr) ((faddr)->s6_addr32[3]) /* @@ -606,8 +731,8 @@ short inp_so_options(const struct inpcb *inp); /* * Flags for inp_flags2. */ -#define INP_LLE_VALID 0x00000001 /* cached lle is valid */ -#define INP_RT_VALID 0x00000002 /* cached rtentry is valid */ +#define INP_2UNUSED1 0x00000001 +#define INP_2UNUSED2 0x00000002 #define INP_PCBGROUPWILD 0x00000004 /* in pcbgroup wildcard list */ #define INP_REUSEPORT 0x00000008 /* SO_REUSEPORT option is set */ #define INP_FREED 0x00000010 /* inp itself is not valid */ @@ -616,7 +741,20 @@ short inp_so_options(const struct inpcb *inp); #define INP_RSS_BUCKET_SET 0x00000080 /* IP_RSS_LISTEN_BUCKET is set */ #define INP_RECVFLOWID 0x00000100 /* populate recv datagram with flow info */ #define INP_RECVRSSBUCKETID 0x00000200 /* populate recv datagram with bucket id */ - +#define INP_RATE_LIMIT_CHANGED 0x00000400 /* rate limit needs attention */ +#define INP_ORIGDSTADDR 0x00000800 /* receive IP dst address/port */ +#define INP_CANNOT_DO_ECN 0x00001000 /* The stack does not do ECN */ +#define INP_REUSEPORT_LB 0x00002000 /* SO_REUSEPORT_LB option is set */ +#define INP_SUPPORTS_MBUFQ 0x00004000 /* Supports the mbuf queue method of LRO */ +#define INP_MBUF_QUEUE_READY 0x00008000 /* The transport is pacing, inputs can be queued */ +#define INP_DONT_SACK_QUEUE 0x00010000 /* If a sack arrives do not wake me */ +#define INP_2PCP_SET 0x00020000 /* If the Eth PCP should be set explicitly */ +#define INP_2PCP_BIT0 0x00040000 /* Eth PCP Bit 0 */ +#define INP_2PCP_BIT1 0x00080000 /* Eth PCP Bit 1 */ +#define INP_2PCP_BIT2 0x00100000 /* Eth PCP Bit 2 */ +#define INP_2PCP_BASE INP_2PCP_BIT0 +#define INP_2PCP_MASK (INP_2PCP_BIT0 | INP_2PCP_BIT1 | INP_2PCP_BIT2) +#define INP_2PCP_SHIFT 18 /* shift PCP field in/out of inp_flags2 */ /* * Flags passed to in_pcblookup*() functions. */ @@ -628,7 +766,6 @@ short inp_so_options(const struct inpcb *inp); INPLOOKUP_WLOCKPCB) #define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb) -#define sotoin6pcb(so) sotoinpcb(so) /* for KAME src sync over BSD*'s */ #define INP_SOCKAF(so) so->so_proto->pr_domain->dom_family @@ -672,7 +809,7 @@ VNET_DECLARE(int, ipport_tcpallocs); void in_pcbinfo_destroy(struct inpcbinfo *); void in_pcbinfo_init(struct inpcbinfo *, const char *, struct inpcbhead *, - int, int, char *, uma_init, uma_fini, uint32_t, u_int); + int, int, char *, uma_init, u_int); int in_pcbbind_check_bindmulti(const struct inpcb *ni, const struct inpcb *oi); @@ -694,13 +831,16 @@ void in_pcbgroup_update_mbuf(struct inpcb *, struct mbuf *); void in_pcbpurgeif0(struct inpcbinfo *, struct ifnet *); int in_pcballoc(struct socket *, struct inpcbinfo *); int in_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *); +int in_pcb_lport_dest(struct inpcb *inp, struct sockaddr *lsa, + u_short *lportp, struct sockaddr *fsa, u_short fport, + struct ucred *cred, int lookupflags); int in_pcb_lport(struct inpcb *, struct in_addr *, u_short *, struct ucred *, int); int in_pcbbind_setup(struct inpcb *, struct sockaddr *, in_addr_t *, u_short *, struct ucred *); int in_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *); int in_pcbconnect_mbuf(struct inpcb *, struct sockaddr *, struct ucred *, - struct mbuf *); + struct mbuf *, bool); int in_pcbconnect_setup(struct inpcb *, struct sockaddr *, in_addr_t *, u_short *, in_addr_t *, u_short *, struct inpcb **, struct ucred *); @@ -709,9 +849,10 @@ void in_pcbdisconnect(struct inpcb *); void in_pcbdrop(struct inpcb *); void in_pcbfree(struct inpcb *); int in_pcbinshash(struct inpcb *); -int in_pcbinshash_nopcbgroup(struct inpcb *); +int in_pcbinshash_mbuf(struct inpcb *, struct mbuf *); int in_pcbladdr(struct inpcb *, struct in_addr *, struct in_addr *, struct ucred *); +int in_pcblbgroup_numa(struct inpcb *, int arg); struct inpcb * in_pcblookup_local(struct inpcbinfo *, struct in_addr, u_short, int, struct ucred *); @@ -729,6 +870,7 @@ void in_pcbrehash_mbuf(struct inpcb *, struct mbuf *); int in_pcbrele(struct inpcb *); int in_pcbrele_rlocked(struct inpcb *); int in_pcbrele_wlocked(struct inpcb *); +void in_pcblist_rele_rlocked(epoch_context_t ctx); void in_losing(struct inpcb *); void in_pcbsetsolabel(struct socket *so); int in_getpeeraddr(struct socket *so, struct sockaddr **nam); @@ -736,6 +878,20 @@ int in_getsockaddr(struct socket *so, struct sockaddr **nam); struct sockaddr * in_sockaddr(in_port_t port, struct in_addr *addr); void in_pcbsosetlabel(struct socket *so); +#ifdef RATELIMIT +int +in_pcboutput_txrtlmt_locked(struct inpcb *, struct ifnet *, + struct mbuf *, uint32_t); +int in_pcbattach_txrtlmt(struct inpcb *, struct ifnet *, uint32_t, uint32_t, + uint32_t, struct m_snd_tag **); +void in_pcbdetach_txrtlmt(struct inpcb *); +void in_pcbdetach_tag(struct m_snd_tag *); +int in_pcbmodify_txrtlmt(struct inpcb *, uint32_t); +int in_pcbquery_txrtlmt(struct inpcb *, uint32_t *); +int in_pcbquery_txrlevel(struct inpcb *, uint32_t *); +void in_pcboutput_txrtlmt(struct inpcb *, struct ifnet *, struct mbuf *); +void in_pcboutput_eagain(struct inpcb *); +#endif #endif /* _KERNEL */ #endif /* !_NETINET_IN_PCB_H_ */ diff --git a/tools/compat/include/netinet/in_systm.h b/tools/compat/include/netinet/in_systm.h index acd2e62a2..538a40263 100644 --- a/tools/compat/include/netinet/in_systm.h +++ b/tools/compat/include/netinet/in_systm.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -55,6 +57,11 @@ typedef u_int32_t n_long; /* long as received from the net */ typedef u_int32_t n_time; /* ms since 00:00 UTC, byte rev */ #ifdef _KERNEL +struct inpcb; +struct ucred; + +int cr_canseeinpcb(struct ucred *cred, struct inpcb *inp); + uint32_t iptime(void); #endif diff --git a/tools/compat/include/netinet/in_var.h b/tools/compat/include/netinet/in_var.h index 0955a9fd8..c7ebff80e 100644 --- a/tools/compat/include/netinet/in_var.h +++ b/tools/compat/include/netinet/in_var.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1985, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -45,4 +47,438 @@ struct in_aliasreq { int ifra_vhid; }; +#ifdef _KERNEL +#include +#include +#include + +struct igmp_ifsoftc; +struct in_multi; +struct lltable; +SLIST_HEAD(in_multi_head, in_multi); + +/* + * IPv4 per-interface state. + */ +struct in_ifinfo { + struct lltable *ii_llt; /* ARP state */ + struct igmp_ifsoftc *ii_igmp; /* IGMP state */ + struct in_multi *ii_allhosts; /* 224.0.0.1 membership */ +}; + +/* + * Interface address, Internet version. One of these structures + * is allocated for each Internet address on an interface. + * The ifaddr structure contains the protocol-independent part + * of the structure and is assumed to be first. + */ +struct in_ifaddr { + struct ifaddr ia_ifa; /* protocol-independent info */ +#define ia_ifp ia_ifa.ifa_ifp +#define ia_flags ia_ifa.ifa_flags + /* ia_subnet{,mask} in host order */ + u_long ia_subnet; /* subnet address */ + u_long ia_subnetmask; /* mask of subnet */ + LIST_ENTRY(in_ifaddr) ia_hash; /* entry in bucket of inet addresses */ + CK_STAILQ_ENTRY(in_ifaddr) ia_link; /* list of internet addresses */ + struct sockaddr_in ia_addr; /* reserve space for interface name */ + struct sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */ +#define ia_broadaddr ia_dstaddr + struct sockaddr_in ia_sockmask; /* reserve space for general netmask */ + struct callout ia_garp_timer; /* timer for retransmitting GARPs */ + int ia_garp_count; /* count of retransmitted GARPs */ +}; + +/* + * Given a pointer to an in_ifaddr (ifaddr), + * return a pointer to the addr as a sockaddr_in. + */ +#define IA_SIN(ia) (&(((struct in_ifaddr *)(ia))->ia_addr)) +#define IA_DSTSIN(ia) (&(((struct in_ifaddr *)(ia))->ia_dstaddr)) +#define IA_MASKSIN(ia) (&(((struct in_ifaddr *)(ia))->ia_sockmask)) + +#define IN_LNAOF(in, ifa) \ + ((ntohl((in).s_addr) & ~((struct in_ifaddr *)(ifa)->ia_subnetmask)) + +extern u_char inetctlerrmap[]; + +#define LLTABLE(ifp) \ + ((struct in_ifinfo *)(ifp)->if_afdata[AF_INET])->ii_llt +/* + * Hash table for IP addresses. + */ +CK_STAILQ_HEAD(in_ifaddrhead, in_ifaddr); +LIST_HEAD(in_ifaddrhashhead, in_ifaddr); + +VNET_DECLARE(struct in_ifaddrhashhead *, in_ifaddrhashtbl); +VNET_DECLARE(struct in_ifaddrhead, in_ifaddrhead); +VNET_DECLARE(u_long, in_ifaddrhmask); /* mask for hash table */ + +#define V_in_ifaddrhashtbl VNET(in_ifaddrhashtbl) +#define V_in_ifaddrhead VNET(in_ifaddrhead) +#define V_in_ifaddrhmask VNET(in_ifaddrhmask) + +#define INADDR_NHASH_LOG2 9 +#define INADDR_NHASH (1 << INADDR_NHASH_LOG2) +#define INADDR_HASHVAL(x) fnv_32_buf((&(x)), sizeof(x), FNV1_32_INIT) +#define INADDR_HASH(x) \ + (&V_in_ifaddrhashtbl[INADDR_HASHVAL(x) & V_in_ifaddrhmask]) + +extern struct rmlock in_ifaddr_lock; + +#define IN_IFADDR_LOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_LOCKED) +#define IN_IFADDR_RLOCK(t) rm_rlock(&in_ifaddr_lock, (t)) +#define IN_IFADDR_RLOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_RLOCKED) +#define IN_IFADDR_RUNLOCK(t) rm_runlock(&in_ifaddr_lock, (t)) +#define IN_IFADDR_WLOCK() rm_wlock(&in_ifaddr_lock) +#define IN_IFADDR_WLOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_WLOCKED) +#define IN_IFADDR_WUNLOCK() rm_wunlock(&in_ifaddr_lock) + +/* + * Macro for finding the internet address structure (in_ifaddr) + * corresponding to one of our IP addresses (in_addr). + */ +#define INADDR_TO_IFADDR(addr, ia) \ + /* struct in_addr addr; */ \ + /* struct in_ifaddr *ia; */ \ +do { \ +\ + LIST_FOREACH(ia, INADDR_HASH((addr).s_addr), ia_hash) \ + if (IA_SIN(ia)->sin_addr.s_addr == (addr).s_addr) \ + break; \ +} while (0) + +/* + * Macro for finding the interface (ifnet structure) corresponding to one + * of our IP addresses. + */ +#define INADDR_TO_IFP(addr, ifp) \ + /* struct in_addr addr; */ \ + /* struct ifnet *ifp; */ \ +{ \ + struct in_ifaddr *ia; \ +\ + INADDR_TO_IFADDR(addr, ia); \ + (ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \ +} + +/* + * Macro for finding the internet address structure (in_ifaddr) corresponding + * to a given interface (ifnet structure). + */ +#define IFP_TO_IA(ifp, ia, t) \ + /* struct ifnet *ifp; */ \ + /* struct in_ifaddr *ia; */ \ + /* struct rm_priotracker *t; */ \ +do { \ + NET_EPOCH_ASSERT(); \ + IN_IFADDR_RLOCK((t)); \ + for ((ia) = CK_STAILQ_FIRST(&V_in_ifaddrhead); \ + (ia) != NULL && (ia)->ia_ifp != (ifp); \ + (ia) = CK_STAILQ_NEXT((ia), ia_link)) \ + continue; \ + IN_IFADDR_RUNLOCK((t)); \ +} while (0) + +/* + * Legacy IPv4 IGMP per-link structure. + */ +struct router_info { + struct ifnet *rti_ifp; + int rti_type; /* type of router which is querier on this interface */ + int rti_time; /* # of slow timeouts since last old query */ + SLIST_ENTRY(router_info) rti_list; +}; + +/* + * IPv4 multicast IGMP-layer source entry. + */ +struct ip_msource { + RB_ENTRY(ip_msource) ims_link; /* RB tree links */ + in_addr_t ims_haddr; /* host byte order */ + struct ims_st { + uint16_t ex; /* # of exclusive members */ + uint16_t in; /* # of inclusive members */ + } ims_st[2]; /* state at t0, t1 */ + uint8_t ims_stp; /* pending query */ +}; + +/* + * IPv4 multicast PCB-layer source entry. + */ +struct in_msource { + RB_ENTRY(ip_msource) ims_link; /* RB tree links */ + in_addr_t ims_haddr; /* host byte order */ + uint8_t imsl_st[2]; /* state before/at commit */ +}; + +RB_HEAD(ip_msource_tree, ip_msource); /* define struct ip_msource_tree */ + +static __inline int +ip_msource_cmp(const struct ip_msource *a, const struct ip_msource *b) +{ + + if (a->ims_haddr < b->ims_haddr) + return (-1); + if (a->ims_haddr == b->ims_haddr) + return (0); + return (1); +} +RB_PROTOTYPE(ip_msource_tree, ip_msource, ims_link, ip_msource_cmp); + +/* + * IPv4 multicast PCB-layer group filter descriptor. + */ +struct in_mfilter { + struct ip_msource_tree imf_sources; /* source list for (S,G) */ + u_long imf_nsrc; /* # of source entries */ + uint8_t imf_st[2]; /* state before/at commit */ + struct in_multi *imf_inm; /* associated multicast address */ + STAILQ_ENTRY(in_mfilter) imf_entry; /* list entry */ +}; + +/* + * Helper types and functions for IPv4 multicast filters. + */ +STAILQ_HEAD(ip_mfilter_head, in_mfilter); + +struct in_mfilter *ip_mfilter_alloc(int mflags, int st0, int st1); +void ip_mfilter_free(struct in_mfilter *); + +static inline void +ip_mfilter_init(struct ip_mfilter_head *head) +{ + + STAILQ_INIT(head); +} + +static inline struct in_mfilter * +ip_mfilter_first(const struct ip_mfilter_head *head) +{ + + return (STAILQ_FIRST(head)); +} + +static inline void +ip_mfilter_insert(struct ip_mfilter_head *head, struct in_mfilter *imf) +{ + + STAILQ_INSERT_TAIL(head, imf, imf_entry); +} + +static inline void +ip_mfilter_remove(struct ip_mfilter_head *head, struct in_mfilter *imf) +{ + + STAILQ_REMOVE(head, imf, in_mfilter, imf_entry); +} + +#define IP_MFILTER_FOREACH(imf, head) \ + STAILQ_FOREACH(imf, head, imf_entry) + +static inline size_t +ip_mfilter_count(struct ip_mfilter_head *head) +{ + struct in_mfilter *imf; + size_t num = 0; + + STAILQ_FOREACH(imf, head, imf_entry) + num++; + return (num); +} + +/* + * IPv4 group descriptor. + * + * For every entry on an ifnet's if_multiaddrs list which represents + * an IP multicast group, there is one of these structures. + * + * If any source filters are present, then a node will exist in the RB-tree + * to permit fast lookup by source whenever an operation takes place. + * This permits pre-order traversal when we issue reports. + * Source filter trees are kept separately from the socket layer to + * greatly simplify locking. + * + * When IGMPv3 is active, inm_timer is the response to group query timer. + * The state-change timer inm_sctimer is separate; whenever state changes + * for the group the state change record is generated and transmitted, + * and kept if retransmissions are necessary. + * + * FUTURE: inm_link is now only used when groups are being purged + * on a detaching ifnet. It could be demoted to a SLIST_ENTRY, but + * because it is at the very start of the struct, we can't do this + * w/o breaking the ABI for ifmcstat. + */ +struct in_multi { + LIST_ENTRY(in_multi) inm_link; /* to-be-released by in_ifdetach */ + struct in_addr inm_addr; /* IP multicast address, convenience */ + struct ifnet *inm_ifp; /* back pointer to ifnet */ + struct ifmultiaddr *inm_ifma; /* back pointer to ifmultiaddr */ + u_int inm_timer; /* IGMPv1/v2 group / v3 query timer */ + u_int inm_state; /* state of the membership */ + void *inm_rti; /* unused, legacy field */ + u_int inm_refcount; /* reference count */ + + /* New fields for IGMPv3 follow. */ + struct igmp_ifsoftc *inm_igi; /* IGMP info */ + SLIST_ENTRY(in_multi) inm_nrele; /* to-be-released by IGMP */ + struct ip_msource_tree inm_srcs; /* tree of sources */ + u_long inm_nsrc; /* # of tree entries */ + + struct mbufq inm_scq; /* queue of pending + * state-change packets */ + struct timeval inm_lastgsrtv; /* Time of last G-S-R query */ + uint16_t inm_sctimer; /* state-change timer */ + uint16_t inm_scrv; /* state-change rexmit count */ + + /* + * SSM state counters which track state at T0 (the time the last + * state-change report's RV timer went to zero) and T1 + * (time of pending report, i.e. now). + * Used for computing IGMPv3 state-change reports. Several refcounts + * are maintained here to optimize for common use-cases. + */ + struct inm_st { + uint16_t iss_fmode; /* IGMP filter mode */ + uint16_t iss_asm; /* # of ASM listeners */ + uint16_t iss_ex; /* # of exclusive members */ + uint16_t iss_in; /* # of inclusive members */ + uint16_t iss_rec; /* # of recorded sources */ + } inm_st[2]; /* state at t0, t1 */ +}; + +/* + * Helper function to derive the filter mode on a source entry + * from its internal counters. Predicates are: + * A source is only excluded if all listeners exclude it. + * A source is only included if no listeners exclude it, + * and at least one listener includes it. + * May be used by ifmcstat(8). + */ +static __inline uint8_t +ims_get_mode(const struct in_multi *inm, const struct ip_msource *ims, + uint8_t t) +{ + + t = !!t; + if (inm->inm_st[t].iss_ex > 0 && + inm->inm_st[t].iss_ex == ims->ims_st[t].ex) + return (MCAST_EXCLUDE); + else if (ims->ims_st[t].in > 0 && ims->ims_st[t].ex == 0) + return (MCAST_INCLUDE); + return (MCAST_UNDEFINED); +} + +#ifdef SYSCTL_DECL +SYSCTL_DECL(_net_inet); +SYSCTL_DECL(_net_inet_ip); +SYSCTL_DECL(_net_inet_raw); +#endif + +/* + * Lock macros for IPv4 layer multicast address lists. IPv4 lock goes + * before link layer multicast locks in the lock order. In most cases, + * consumers of IN_*_MULTI() macros should acquire the locks before + * calling them; users of the in_{add,del}multi() functions should not. + */ +extern struct mtx in_multi_list_mtx; +extern struct sx in_multi_sx; + +#define IN_MULTI_LIST_LOCK() mtx_lock(&in_multi_list_mtx) +#define IN_MULTI_LIST_UNLOCK() mtx_unlock(&in_multi_list_mtx) +#define IN_MULTI_LIST_LOCK_ASSERT() mtx_assert(&in_multi_list_mtx, MA_OWNED) +#define IN_MULTI_LIST_UNLOCK_ASSERT() mtx_assert(&in_multi_list_mtx, MA_NOTOWNED) + +#define IN_MULTI_LOCK() sx_xlock(&in_multi_sx) +#define IN_MULTI_UNLOCK() sx_xunlock(&in_multi_sx) +#define IN_MULTI_LOCK_ASSERT() sx_assert(&in_multi_sx, SA_XLOCKED) +#define IN_MULTI_UNLOCK_ASSERT() sx_assert(&in_multi_sx, SA_XUNLOCKED) + +void inm_disconnect(struct in_multi *inm); +extern int ifma_restart; + +/* Acquire an in_multi record. */ +static __inline void +inm_acquire_locked(struct in_multi *inm) +{ + + IN_MULTI_LIST_LOCK_ASSERT(); + ++inm->inm_refcount; +} + +static __inline void +inm_acquire(struct in_multi *inm) +{ + IN_MULTI_LIST_LOCK(); + inm_acquire_locked(inm); + IN_MULTI_LIST_UNLOCK(); +} + +static __inline void +inm_rele_locked(struct in_multi_head *inmh, struct in_multi *inm) +{ + MPASS(inm->inm_refcount > 0); + IN_MULTI_LIST_LOCK_ASSERT(); + + if (--inm->inm_refcount == 0) { + MPASS(inmh != NULL); + inm_disconnect(inm); + inm->inm_ifma->ifma_protospec = NULL; + SLIST_INSERT_HEAD(inmh, inm, inm_nrele); + } +} + +/* + * Return values for imo_multi_filter(). + */ +#define MCAST_PASS 0 /* Pass */ +#define MCAST_NOTGMEMBER 1 /* This host not a member of group */ +#define MCAST_NOTSMEMBER 2 /* This host excluded source */ +#define MCAST_MUTED 3 /* [deprecated] */ + +struct rib_head; +struct ip_moptions; + +struct in_multi *inm_lookup_locked(struct ifnet *, const struct in_addr); +struct in_multi *inm_lookup(struct ifnet *, const struct in_addr); +int imo_multi_filter(const struct ip_moptions *, const struct ifnet *, + const struct sockaddr *, const struct sockaddr *); +void inm_commit(struct in_multi *); +void inm_clear_recorded(struct in_multi *); +void inm_print(const struct in_multi *); +int inm_record_source(struct in_multi *inm, const in_addr_t); +void inm_release_deferred(struct in_multi *); +void inm_release_list_deferred(struct in_multi_head *); +void inm_release_wait(void *); +struct in_multi * +in_addmulti(struct in_addr *, struct ifnet *); +int in_joingroup(struct ifnet *, const struct in_addr *, + /*const*/ struct in_mfilter *, struct in_multi **); +int in_joingroup_locked(struct ifnet *, const struct in_addr *, + /*const*/ struct in_mfilter *, struct in_multi **); +int in_leavegroup(struct in_multi *, /*const*/ struct in_mfilter *); +int in_leavegroup_locked(struct in_multi *, + /*const*/ struct in_mfilter *); +int in_control(struct socket *, u_long, caddr_t, struct ifnet *, + struct thread *); +int in_addprefix(struct in_ifaddr *); +int in_scrubprefix(struct in_ifaddr *, u_int); +void in_ifscrub_all(void); +int in_handle_ifaddr_route(int, struct in_ifaddr *); +void ip_input(struct mbuf *); +void ip_direct_input(struct mbuf *); +void in_ifadown(struct ifaddr *ifa, int); +struct mbuf *ip_tryforward(struct mbuf *); +void *in_domifattach(struct ifnet *); +void in_domifdetach(struct ifnet *, void *); +struct rib_head *in_inithead(uint32_t fibnum); +#ifdef VIMAGE +void in_detachhead(struct rib_head *rh); +#endif + +#endif /* _KERNEL */ + +/* INET6 stuff */ +#include + #endif /* _NETINET_IN_VAR_H_ */ diff --git a/tools/compat/include/netinet/ip.h b/tools/compat/include/netinet/ip.h index 58ad363e1..0642121fc 100644 --- a/tools/compat/include/netinet/ip.h +++ b/tools/compat/include/netinet/ip.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. * All rights reserved. @@ -11,7 +13,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -91,6 +93,11 @@ struct ip { #define IPTOS_PREC_PRIORITY IPTOS_DSCP_CS1 #define IPTOS_PREC_ROUTINE IPTOS_DSCP_CS0 +/* + * Offset of Diffserv decimal value to convert it to tos value . + */ +#define IPTOS_DSCP_OFFSET 2 + /* * Definitions for DiffServ Codepoints as per RFC2474 and RFC5865. */ diff --git a/tools/compat/include/netinet/ip_carp.h b/tools/compat/include/netinet/ip_carp.h index 023d937a3..1db2e5283 100644 --- a/tools/compat/include/netinet/ip_carp.h +++ b/tools/compat/include/netinet/ip_carp.h @@ -1,7 +1,9 @@ /* $FreeBSD$ */ /* $OpenBSD: ip_carp.h,v 1.8 2004/07/29 22:12:15 mcbride Exp $ */ -/* +/*- + * SPDX-License-Identifier: BSD-2-Clause + * * Copyright (c) 2002 Michael Shalayeff. All rights reserved. * Copyright (c) 2003 Ryan McBride. All rights reserved. * @@ -135,4 +137,45 @@ struct carpreq { #define SIOCSVH _IOWR('i', 245, struct ifreq) #define SIOCGVH _IOWR('i', 246, struct ifreq) +#ifdef _KERNEL +int carp_ioctl(struct ifreq *, u_long, struct thread *); +int carp_attach(struct ifaddr *, int); +void carp_detach(struct ifaddr *, bool); +void carp_carpdev_state(struct ifnet *); +int carp_input(struct mbuf **, int *, int); +int carp6_input (struct mbuf **, int *, int); +int carp_output (struct ifnet *, struct mbuf *, + const struct sockaddr *); +int carp_master(struct ifaddr *); +int carp_iamatch(struct ifaddr *, uint8_t **); +struct ifaddr *carp_iamatch6(struct ifnet *, struct in6_addr *); +char * carp_macmatch6(struct ifnet *, struct mbuf *, const struct in6_addr *); +int carp_forus(struct ifnet *, u_char *); + +/* These are external networking stack hooks for CARP */ +/* net/if.c */ +extern int (*carp_ioctl_p)(struct ifreq *, u_long, struct thread *); +extern int (*carp_attach_p)(struct ifaddr *, int); +extern void (*carp_detach_p)(struct ifaddr *, bool); +extern void (*carp_linkstate_p)(struct ifnet *); +extern void (*carp_demote_adj_p)(int, char *); +extern int (*carp_master_p)(struct ifaddr *); +/* net/if_bridge.c net/if_ethersubr.c */ +extern int (*carp_forus_p)(struct ifnet *, u_char *); +/* net/if_ethersubr.c */ +extern int (*carp_output_p)(struct ifnet *, struct mbuf *, + const struct sockaddr *); +/* net/rtsock.c */ +extern int (*carp_get_vhid_p)(struct ifaddr *); +#ifdef INET +/* netinet/if_ether.c */ +extern int (*carp_iamatch_p)(struct ifaddr *, uint8_t **); +#endif +#ifdef INET6 +/* netinet6/nd6_nbr.c */ +extern struct ifaddr *(*carp_iamatch6_p)(struct ifnet *, struct in6_addr *); +extern char * (*carp_macmatch6_p)(struct ifnet *, struct mbuf *, + const struct in6_addr *); +#endif +#endif #endif /* _IP_CARP_H */ diff --git a/tools/compat/include/netinet/ip_fw.h b/tools/compat/include/netinet/ip_fw.h index 6475fe088..88f4a398c 100644 --- a/tools/compat/include/netinet/ip_fw.h +++ b/tools/compat/include/netinet/ip_fw.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa * * Redistribution and use in source and binary forms, with or without @@ -32,7 +34,7 @@ * The default rule number. By the design of ip_fw, the default rule * is the last one, so its number can also serve as the highest number * allowed for a rule. The ip_fw code relies on both meanings of this - * constant. + * constant. */ #define IPFW_DEFAULT_RULE 65535 @@ -110,6 +112,35 @@ typedef struct _ip_fw3_opheader { #define IP_FW_DUMP_SOPTCODES 116 /* Dump available sopts/versions */ #define IP_FW_DUMP_SRVOBJECTS 117 /* Dump existing named objects */ +#define IP_FW_NAT64STL_CREATE 130 /* Create stateless NAT64 instance */ +#define IP_FW_NAT64STL_DESTROY 131 /* Destroy stateless NAT64 instance */ +#define IP_FW_NAT64STL_CONFIG 132 /* Modify stateless NAT64 instance */ +#define IP_FW_NAT64STL_LIST 133 /* List stateless NAT64 instances */ +#define IP_FW_NAT64STL_STATS 134 /* Get NAT64STL instance statistics */ +#define IP_FW_NAT64STL_RESET_STATS 135 /* Reset NAT64STL instance statistics */ + +#define IP_FW_NAT64LSN_CREATE 140 /* Create stateful NAT64 instance */ +#define IP_FW_NAT64LSN_DESTROY 141 /* Destroy stateful NAT64 instance */ +#define IP_FW_NAT64LSN_CONFIG 142 /* Modify stateful NAT64 instance */ +#define IP_FW_NAT64LSN_LIST 143 /* List stateful NAT64 instances */ +#define IP_FW_NAT64LSN_STATS 144 /* Get NAT64LSN instance statistics */ +#define IP_FW_NAT64LSN_LIST_STATES 145 /* Get stateful NAT64 states */ +#define IP_FW_NAT64LSN_RESET_STATS 146 /* Reset NAT64LSN instance statistics */ + +#define IP_FW_NPTV6_CREATE 150 /* Create NPTv6 instance */ +#define IP_FW_NPTV6_DESTROY 151 /* Destroy NPTv6 instance */ +#define IP_FW_NPTV6_CONFIG 152 /* Modify NPTv6 instance */ +#define IP_FW_NPTV6_LIST 153 /* List NPTv6 instances */ +#define IP_FW_NPTV6_STATS 154 /* Get NPTv6 instance statistics */ +#define IP_FW_NPTV6_RESET_STATS 155 /* Reset NPTv6 instance statistics */ + +#define IP_FW_NAT64CLAT_CREATE 160 /* Create clat NAT64 instance */ +#define IP_FW_NAT64CLAT_DESTROY 161 /* Destroy clat NAT64 instance */ +#define IP_FW_NAT64CLAT_CONFIG 162 /* Modify clat NAT64 instance */ +#define IP_FW_NAT64CLAT_LIST 163 /* List clat NAT64 instances */ +#define IP_FW_NAT64CLAT_STATS 164 /* Get NAT64CLAT instance statistics */ +#define IP_FW_NAT64CLAT_RESET_STATS 165 /* Reset NAT64CLAT instance statistics */ + /* * The kernel representation of ipfw rules is made of a list of * 'instructions' (for all practical purposes equivalent to BPF @@ -208,7 +239,7 @@ enum ipfw_opcodes { /* arguments (4 byte each) */ O_FORWARD_MAC, /* fwd mac */ O_NAT, /* nope */ O_REASS, /* none */ - + /* * More opcodes. */ @@ -246,7 +277,7 @@ enum ipfw_opcodes { /* arguments (4 byte each) */ O_SETFIB, /* arg1=FIB number */ O_FIB, /* arg1=FIB desired fib number */ - + O_SOCKARG, /* socket argument */ O_CALLRETURN, /* arg1=called rule number */ @@ -259,6 +290,10 @@ enum ipfw_opcodes { /* arguments (4 byte each) */ O_EXTERNAL_ACTION, /* arg1=id of external action handler */ O_EXTERNAL_INSTANCE, /* arg1=id of eaction handler instance */ + O_EXTERNAL_DATA, /* variable length data */ + + O_SKIP_ACTION, /* none */ + O_TCPMSS, /* arg1=MSS value */ O_LAST_OPCODE /* not an opcode! */ }; @@ -304,7 +339,7 @@ enum ipfw_opcodes { /* arguments (4 byte each) */ * */ typedef struct _ipfw_insn { /* template for instructions */ - u_int8_t opcode; + _Alignas(_Alignof(u_int32_t)) u_int8_t opcode; u_int8_t len; /* number of 32-bit words */ #define F_NOT 0x80 #define F_OR 0x40 @@ -450,9 +485,9 @@ struct cfg_redir { u_short pport_cnt; /* number of public ports */ u_short rport_cnt; /* number of remote ports */ int proto; /* protocol: tcp/udp */ - struct alias_link **alink; + struct alias_link **alink; /* num of entry in spool chain */ - u_int16_t spool_cnt; + u_int16_t spool_cnt; /* chain of spool instances */ LIST_HEAD(spool_chain, cfg_spool) spool_chain; }; @@ -469,9 +504,9 @@ struct cfg_nat { int mode; /* aliasing mode */ struct libalias *lib; /* libalias instance */ /* number of entry in spool chain */ - int redir_cnt; + int redir_cnt; /* chain of redir instances */ - LIST_HEAD(redir_chain, cfg_redir) redir_chain; + LIST_HEAD(redir_chain, cfg_redir) redir_chain; }; #endif @@ -481,7 +516,6 @@ struct cfg_nat { #endif /* ifndef _KERNEL */ - struct nat44_cfg_spool { struct in_addr addr; uint16_t port; @@ -502,7 +536,7 @@ struct nat44_cfg_redir { uint16_t pport_cnt; /* number of public ports */ uint16_t rport_cnt; /* number of remote ports */ uint16_t mode; /* type of redirect mode */ - uint16_t spool_cnt; /* num of entry in spool chain */ + uint16_t spool_cnt; /* num of entry in spool chain */ uint16_t spare; uint32_t proto; /* protocol: tcp/udp */ }; @@ -520,15 +554,16 @@ struct nat44_cfg_nat { /* Nat command. */ typedef struct _ipfw_insn_nat { ipfw_insn o; - struct cfg_nat *nat; + struct cfg_nat *nat; } ipfw_insn_nat; /* Apply ipv6 mask on ipv6 addr */ -#define APPLY_MASK(addr,mask) \ +#define APPLY_MASK(addr,mask) do { \ (addr)->__u6_addr.__u6_addr32[0] &= (mask)->__u6_addr.__u6_addr32[0]; \ (addr)->__u6_addr.__u6_addr32[1] &= (mask)->__u6_addr.__u6_addr32[1]; \ (addr)->__u6_addr.__u6_addr32[2] &= (mask)->__u6_addr.__u6_addr32[2]; \ - (addr)->__u6_addr.__u6_addr32[3] &= (mask)->__u6_addr.__u6_addr32[3]; + (addr)->__u6_addr.__u6_addr32[3] &= (mask)->__u6_addr.__u6_addr32[3]; \ +} while (0) /* Structure for ipv6 */ typedef struct _ipfw_insn_ip6 { @@ -543,7 +578,7 @@ typedef struct _ipfw_insn_icmp6 { uint32_t d[7]; /* XXX This number si related to the netinet/icmp6.h * define ICMP6_MAXTYPE * as follows: n = ICMP6_MAXTYPE/32 + 1 - * Actually is 203 + * Actually is 203 */ } ipfw_insn_icmp6; @@ -588,6 +623,7 @@ struct ip_fw_rule { ipfw_insn cmd[1]; /* storage for commands */ }; #define IPFW_RULE_NOOPT 0x01 /* Has no options in body */ +#define IPFW_RULE_JUSTOPTS 0x02 /* new format of rule body */ /* Unaligned version */ @@ -601,7 +637,6 @@ struct ip_fw_bcounter { uint64_t bcnt; /* Byte counter */ }; - #ifndef _KERNEL /* * Legacy rule format @@ -632,7 +667,6 @@ struct ip_fw { #define RULESIZE(rule) (sizeof(*(rule)) + (rule)->cmd_len * 4 - 4) - #if 1 // should be moved to in.h /* * This structure is used as a flow mask and a flow id for various @@ -646,7 +680,7 @@ struct ipfw_flow_id { uint32_t src_ip; uint16_t dst_port; uint16_t src_port; - uint8_t fib; + uint8_t fib; /* XXX: must be uint16_t */ uint8_t proto; uint8_t _flags; /* protocol-specific flags */ uint8_t addr_type; /* 4=ip4, 6=ip6, 1=ether ? */ @@ -657,6 +691,7 @@ struct ipfw_flow_id { }; #endif +#define IS_IP4_FLOW_ID(id) ((id)->addr_type == 4) #define IS_IP6_FLOW_ID(id) ((id)->addr_type == 6) /* @@ -678,12 +713,14 @@ struct _ipfw_dyn_rule { u_int32_t state; /* state of this rule (typically a * combination of TCP flags) */ +#define IPFW_DYN_ORPHANED 0x40000 /* state's parent rule was deleted */ u_int32_t ack_fwd; /* most recent ACKs in forward */ u_int32_t ack_rev; /* and reverse directions (used */ /* to generate keepalives) */ u_int16_t dyn_type; /* rule type */ u_int16_t count; /* refcount */ -}; + u_int16_t kidx; /* index of named object */ +} __attribute__ ((packed)) __attribute__((__aligned__(8))); /* * Definitions for IP option names. @@ -704,6 +741,8 @@ struct _ipfw_dyn_rule { #define ICMP_REJECT_RST 0x100 /* fake ICMP code (send a TCP RST) */ #define ICMP6_UNREACH_RST 0x100 /* fake ICMPv6 code (send a TCP RST) */ +#define ICMP_REJECT_ABORT 0x101 /* fake ICMP code (send an SCTP ABORT) */ +#define ICMP6_UNREACH_ABORT 0x101 /* fake ICMPv6 code (send an SCTP ABORT) */ /* * These are used for lookup tables. @@ -784,10 +823,18 @@ typedef struct _ipfw_obj_tlv { #define IPFW_TLV_TBLENT_LIST 8 #define IPFW_TLV_RANGE 9 #define IPFW_TLV_EACTION 10 +#define IPFW_TLV_COUNTERS 11 +#define IPFW_TLV_OBJDATA 12 +#define IPFW_TLV_STATE_NAME 14 #define IPFW_TLV_EACTION_BASE 1000 #define IPFW_TLV_EACTION_NAME(arg) (IPFW_TLV_EACTION_BASE + (arg)) +typedef struct _ipfw_obj_data { + ipfw_obj_tlv head; + void *data[0]; +} ipfw_obj_data; + /* Object name TLV */ typedef struct _ipfw_obj_ntlv { ipfw_obj_tlv head; /* TLV header */ @@ -850,7 +897,7 @@ typedef struct _ipfw_obj_tentry { uint32_t key; /* uid/gid/port */ struct in6_addr addr6; /* IPv6 address */ char iface[IF_NAMESIZE]; /* interface name */ - struct tflow_entry flow; + struct tflow_entry flow; } k; union { ipfw_table_value value; /* value data */ @@ -897,9 +944,10 @@ typedef struct _ipfw_range_tlv { #define IPFW_RCFLAG_RANGE 0x01 /* rule range is set */ #define IPFW_RCFLAG_ALL 0x02 /* match ALL rules */ #define IPFW_RCFLAG_SET 0x04 /* match rules in given set */ +#define IPFW_RCFLAG_DYNAMIC 0x08 /* match only dynamic states */ /* User-settable flags */ #define IPFW_RCFLAG_USER (IPFW_RCFLAG_RANGE | IPFW_RCFLAG_ALL | \ - IPFW_RCFLAG_SET) + IPFW_RCFLAG_SET | IPFW_RCFLAG_DYNAMIC) /* Internally used flags */ #define IPFW_RCFLAG_DEFAULT 0x0100 /* Do not skip defaul rule */ diff --git a/tools/compat/include/netinet/ip_icmp.h b/tools/compat/include/netinet/ip_icmp.h index 64db00648..0303a0950 100644 --- a/tools/compat/include/netinet/ip_icmp.h +++ b/tools/compat/include/netinet/ip_icmp.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/tools/compat/include/netinet/ip_mroute.h b/tools/compat/include/netinet/ip_mroute.h index 65f7d83ca..054eb921d 100644 --- a/tools/compat/include/netinet/ip_mroute.h +++ b/tools/compat/include/netinet/ip_mroute.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1989 Stephen Deering. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -14,7 +16,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -249,7 +251,6 @@ struct sioc_vif_req { u_long obytes; /* Output byte count on vif */ }; - /* * The kernel's virtual-interface structure. */ diff --git a/tools/compat/include/netinet/ip_var.h b/tools/compat/include/netinet/ip_var.h index 847704fd1..77b6ee885 100644 --- a/tools/compat/include/netinet/ip_var.h +++ b/tools/compat/include/netinet/ip_var.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -34,6 +36,7 @@ #define _NETINET_IP_VAR_H_ #include +#include /* * Overlay for ip header used by other protocols (tcp, udp). @@ -58,6 +61,7 @@ struct ipq { u_char ipq_ttl; /* time for reass q to live */ u_char ipq_p; /* protocol of this fragment */ u_short ipq_id; /* sequence id for reassembly */ + int ipq_maxoff; /* total length of packet */ struct mbuf *ipq_frags; /* to ip headers of fragments */ struct in_addr ipq_src,ipq_dst; u_char ipq_nfrags; /* # frags in this packet */ @@ -78,6 +82,7 @@ struct ipoption { char ipopt_list[MAX_IPOPTLEN]; /* options proper */ }; +#if defined(_NETINET_IN_VAR_H_) && defined(_KERNEL) /* * Structure attached to inpcb.ip_moptions and * passed to ip_output when IP multicast options are in use. @@ -89,12 +94,11 @@ struct ip_moptions { u_long imo_multicast_vif; /* vif num outgoing multicasts */ u_char imo_multicast_ttl; /* TTL for outgoing multicasts */ u_char imo_multicast_loop; /* 1 => hear sends if a member */ - u_short imo_num_memberships; /* no. memberships this socket */ - u_short imo_max_memberships; /* max memberships this socket */ - struct in_multi **imo_membership; /* group memberships */ - struct in_mfilter *imo_mfilters; /* source filters */ - STAILQ_ENTRY(ip_moptions) imo_link; + struct ip_mfilter_head imo_head; /* group membership list */ }; +#else +struct ip_moptions; +#endif struct ipstat { uint64_t ips_total; /* total packets received */ @@ -162,6 +166,7 @@ void kmod_ipstat_dec(int statnum); #define IP_ROUTETOIF SO_DONTROUTE /* 0x10 bypass routing tables */ #define IP_ALLOWBROADCAST SO_BROADCAST /* 0x20 can send broadcast packets */ #define IP_NODEFAULTFLOWID 0x40 /* Don't set the flowid from inp */ +#define IP_NO_SND_TAG_RL 0x80 /* Don't send down the ratelimit tag */ #ifdef __NO_STRICT_ALIGNMENT #define IP_HDR_ALIGNED_P(ip) 1 @@ -173,9 +178,11 @@ struct ip; struct inpcb; struct route; struct sockopt; +struct inpcbinfo; VNET_DECLARE(int, ip_defttl); /* default IP ttl */ VNET_DECLARE(int, ipforwarding); /* ip forwarding */ +VNET_DECLARE(int, ipsendredirects); #ifdef IPSTEALTH VNET_DECLARE(int, ipstealth); /* stealth forwarding */ #endif @@ -191,6 +198,7 @@ extern struct pr_usrreqs rip_usrreqs; #define V_ip_id VNET(ip_id) #define V_ip_defttl VNET(ip_defttl) #define V_ipforwarding VNET(ipforwarding) +#define V_ipsendredirects VNET(ipsendredirects) #ifdef IPSTEALTH #define V_ipstealth VNET(ipstealth) #endif @@ -236,8 +244,9 @@ extern int (*ip_rsvp_vif)(struct socket *, struct sockopt *); extern void (*ip_rsvp_force_done)(struct socket *); extern int (*rsvp_input_p)(struct mbuf **, int *, int); -VNET_DECLARE(struct pfil_head, inet_pfil_hook); /* packet filter hooks */ -#define V_inet_pfil_hook VNET(inet_pfil_hook) +VNET_DECLARE(struct pfil_head *, inet_pfil_head); +#define V_inet_pfil_head VNET(inet_pfil_head) +#define PFIL_INET_NAME "inet" void in_delayed_cksum(struct mbuf *m); @@ -286,13 +295,11 @@ VNET_DECLARE(ip_fw_ctl_ptr_t, ip_fw_ctl_ptr); #define V_ip_fw_ctl_ptr VNET(ip_fw_ctl_ptr) /* Divert hooks. */ -extern void (*ip_divert_ptr)(struct mbuf *m, int incoming); +extern void (*ip_divert_ptr)(struct mbuf *m, bool incoming); /* ng_ipfw hooks -- XXX make it the same as divert and dummynet */ -extern int (*ng_ipfw_input_p)(struct mbuf **, int, - struct ip_fw_args *, int); - +extern int (*ng_ipfw_input_p)(struct mbuf **, struct ip_fw_args *, bool); extern int (*ip_dn_ctl_ptr)(struct sockopt *); -extern int (*ip_dn_io_ptr)(struct mbuf **, int, struct ip_fw_args *); +extern int (*ip_dn_io_ptr)(struct mbuf **, struct ip_fw_args *); #endif /* _KERNEL */ #endif /* !_NETINET_IP_VAR_H_ */ diff --git a/tools/compat/include/netinet/pim_var.h b/tools/compat/include/netinet/pim_var.h index ae876c948..dfb06928d 100644 --- a/tools/compat/include/netinet/pim_var.h +++ b/tools/compat/include/netinet/pim_var.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1998-2000 * University of Southern California/Information Sciences Institute. * All rights reserved. @@ -71,8 +73,6 @@ struct pimstat { #define PIMCTL_STATS 1 /* statistics (read-only) */ #ifdef _KERNEL - -int pim_input(struct mbuf **, int *, int); SYSCTL_DECL(_net_inet_pim); #endif diff --git a/tools/compat/include/netinet/sctp.h b/tools/compat/include/netinet/sctp.h index ec42cffaf..d67b33acd 100644 --- a/tools/compat/include/netinet/sctp.h +++ b/tools/compat/include/netinet/sctp.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. @@ -36,10 +38,8 @@ __FBSDID("$FreeBSD$"); #ifndef _NETINET_SCTP_H_ #define _NETINET_SCTP_H_ - #include - #define SCTP_PACKED __attribute__((packed)) /* @@ -182,7 +182,6 @@ struct sctp_paramhdr { #define SCTP_STREAM_RESET_INCOMING 0x00000001 #define SCTP_STREAM_RESET_OUTGOING 0x00000002 - /* here on down are more implementation specific */ #define SCTP_SET_DEBUG_LEVEL 0x00001005 #define SCTP_CLR_STAT_LOG 0x00001007 @@ -205,7 +204,6 @@ struct sctp_paramhdr { #define SCTP_PCB_STATUS 0x00001104 #define SCTP_GET_NONCE_VALUES 0x00001105 - /* Special hook for dynamically setting primary for all assoc's, * this is a write only option that requires root privilege. */ @@ -320,7 +318,6 @@ struct sctp_paramhdr { /* First-come, first-serve */ #define SCTP_SS_FIRST_COME 0x00000005 - /* fragment interleave constants * setting must be one of these or * EINVAL returned. @@ -417,7 +414,7 @@ struct sctp_error_unresolv_addr { struct sctp_error_unrecognized_chunk { struct sctp_error_cause cause; /* code=SCTP_CAUSE_UNRECOG_CHUNK */ - struct sctp_chunkhdr ch;/* header from chunk in error */ + struct sctp_chunkhdr ch; /* header from chunk in error */ } SCTP_PACKED; struct sctp_error_no_user_data { @@ -514,6 +511,7 @@ struct sctp_error_auth_invalid_hmac { #define SCTP_PCB_FLAGS_BOUNDALL 0x00000004 #define SCTP_PCB_FLAGS_ACCEPTING 0x00000008 #define SCTP_PCB_FLAGS_UNBOUND 0x00000010 +#define SCTP_PCB_FLAGS_SND_ITERATOR_UP 0x00000020 #define SCTP_PCB_FLAGS_CLOSE_IP 0x00040000 #define SCTP_PCB_FLAGS_WAS_CONNECTED 0x00080000 #define SCTP_PCB_FLAGS_WAS_ABORTED 0x00100000 @@ -545,7 +543,6 @@ struct sctp_error_auth_invalid_hmac { #define SCTP_PCB_FLAGS_INTERLEAVE_STRMS 0x0000000000000010 #define SCTP_PCB_FLAGS_DO_ASCONF 0x0000000000000020 #define SCTP_PCB_FLAGS_AUTO_ASCONF 0x0000000000000040 -#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE 0x0000000000000080 /* socket options */ #define SCTP_PCB_FLAGS_NODELAY 0x0000000000000100 #define SCTP_PCB_FLAGS_AUTOCLOSE 0x0000000000000200 @@ -581,9 +578,10 @@ struct sctp_error_auth_invalid_hmac { #define SCTP_MOBILITY_FASTHANDOFF 0x00000002 #define SCTP_MOBILITY_PRIM_DELETED 0x00000004 - -#define SCTP_SMALLEST_PMTU 512 /* smallest pmtu allowed when disabling PMTU - * discovery */ +/* Smallest PMTU allowed when disabling PMTU discovery */ +#define SCTP_SMALLEST_PMTU 512 +/* Largest PMTU allowed when disabling PMTU discovery */ +#define SCTP_LARGEST_PMTU 65536 #undef SCTP_PACKED @@ -601,9 +599,9 @@ struct sctp_error_auth_invalid_hmac { */ #define SCTP_MAX_SACK_DELAY 500 /* per RFC4960 */ #define SCTP_MAX_HB_INTERVAL 14400000 /* 4 hours in ms */ +#define SCTP_MIN_COOKIE_LIFE 1000 /* 1 second in ms */ #define SCTP_MAX_COOKIE_LIFE 3600000 /* 1 hour in ms */ - /* Types of logging/KTR tracing that can be enabled via the * sysctl net.inet.sctp.sctp_logging. You must also enable * SUBSYS tracing. diff --git a/tools/compat/include/netinet/sctp_constants.h b/tools/compat/include/netinet/sctp_constants.h index ecde4fee5..28c543f88 100644 --- a/tools/compat/include/netinet/sctp_constants.h +++ b/tools/compat/include/netinet/sctp_constants.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. @@ -36,7 +38,6 @@ __FBSDID("$FreeBSD$"); #ifndef _NETINET_SCTP_CONSTANTS_H_ #define _NETINET_SCTP_CONSTANTS_H_ - /* IANA assigned port number for SCTP over UDP encapsulation */ #define SCTP_OVER_UDP_TUNNELING_PORT 9899 @@ -85,22 +86,16 @@ __FBSDID("$FreeBSD$"); /* #define SCTP_AUDITING_ENABLED 1 used for debug/auditing */ #define SCTP_AUDIT_SIZE 256 - #define SCTP_KTRHEAD_NAME "sctp_iterator" #define SCTP_KTHREAD_PAGES 0 #define SCTP_MCORE_NAME "sctp_core_worker" - /* If you support Multi-VRF how big to * make the initial array of VRF's to. */ #define SCTP_DEFAULT_VRF_SIZE 4 -/* constants for rto calc */ -#define sctp_align_safe_nocopy 0 -#define sctp_align_unsafe_makecopy 1 - /* JRS - Values defined for the HTCP algorithm */ #define ALPHA_BASE (1<<7) /* 1.0 with shift << 7 */ #define BETA_MIN (1<<6) /* 0.5 with shift << 7 */ @@ -265,7 +260,6 @@ __FBSDID("$FreeBSD$"); #define SCTP_LOCK_UNKNOWN 2 - /* number of associations by default for zone allocation */ #define SCTP_MAX_NUM_OF_ASOC 40000 /* how many addresses per assoc remote and local */ @@ -390,7 +384,6 @@ __FBSDID("$FreeBSD$"); #define IS_SCTP_CONTROL(a) (((a)->chunk_type != SCTP_DATA) && ((a)->chunk_type != SCTP_IDATA)) #define IS_SCTP_DATA(a) (((a)->chunk_type == SCTP_DATA) || ((a)->chunk_type == SCTP_IDATA)) - /* SCTP parameter types */ /*************0x0000 series*************/ #define SCTP_HEARTBEAT_INFO 0x0001 @@ -402,43 +395,34 @@ __FBSDID("$FreeBSD$"); #define SCTP_HOSTNAME_ADDRESS 0x000b #define SCTP_SUPPORTED_ADDRTYPE 0x000c -/* draft-ietf-stewart-tsvwg-strreset-xxx */ +/* RFC 6525 */ #define SCTP_STR_RESET_OUT_REQUEST 0x000d #define SCTP_STR_RESET_IN_REQUEST 0x000e #define SCTP_STR_RESET_TSN_REQUEST 0x000f #define SCTP_STR_RESET_RESPONSE 0x0010 #define SCTP_STR_RESET_ADD_OUT_STREAMS 0x0011 -#define SCTP_STR_RESET_ADD_IN_STREAMS 0x0012 +#define SCTP_STR_RESET_ADD_IN_STREAMS 0x0012 #define SCTP_MAX_RESET_PARAMS 2 -#define SCTP_STREAM_RESET_TSN_DELTA 0x1000 +#define SCTP_STREAM_RESET_TSN_DELTA 0x1000 /*************0x4000 series*************/ /*************0x8000 series*************/ #define SCTP_ECN_CAPABLE 0x8000 -/* draft-ietf-tsvwg-auth-xxx */ +/* RFC 4895 */ #define SCTP_RANDOM 0x8002 #define SCTP_CHUNK_LIST 0x8003 #define SCTP_HMAC_LIST 0x8004 -/* - * draft-ietf-tsvwg-addip-sctp-xx param=0x8008 len=0xNNNN Byte | Byte | Byte - * | Byte Byte | Byte ... - * - * Where each byte is a chunk type extension supported. For example, to support - * all chunks one would have (in hex): - * - * 80 01 00 09 C0 C1 80 81 82 00 00 00 - * - * Has the parameter. C0 = PR-SCTP (RFC3758) C1, 80 = ASCONF (addip draft) 81 - * = Packet Drop 82 = Stream Reset 83 = Authentication - */ -#define SCTP_SUPPORTED_CHUNK_EXT 0x8008 +/* RFC 4820 */ +#define SCTP_PAD 0x8005 +/* RFC 5061 */ +#define SCTP_SUPPORTED_CHUNK_EXT 0x8008 /*************0xC000 series*************/ #define SCTP_PRSCTP_SUPPORTED 0xc000 -/* draft-ietf-tsvwg-addip-sctp */ +/* RFC 5061 */ #define SCTP_ADD_IP_ADDRESS 0xc001 #define SCTP_DEL_IP_ADDRESS 0xc002 #define SCTP_ERROR_CAUSE_IND 0xc003 @@ -446,8 +430,8 @@ __FBSDID("$FreeBSD$"); #define SCTP_SUCCESS_REPORT 0xc005 #define SCTP_ULP_ADAPTATION 0xc006 /* behave-nat-draft */ -#define SCTP_HAS_NAT_SUPPORT 0xc007 -#define SCTP_NAT_VTAGS 0xc008 +#define SCTP_HAS_NAT_SUPPORT 0xc007 +#define SCTP_NAT_VTAGS 0xc008 /* bits for TOS field */ #define SCTP_ECT0_BIT 0x02 @@ -461,7 +445,6 @@ __FBSDID("$FreeBSD$"); /* mask to get sticky */ #define SCTP_STICKY_OPTIONS_MASK 0x0c - /* * SCTP states for internal state machine */ @@ -481,10 +464,14 @@ __FBSDID("$FreeBSD$"); #define SCTP_STATE_IN_ACCEPT_QUEUE 0x1000 #define SCTP_STATE_MASK 0x007f -#define SCTP_GET_STATE(asoc) ((asoc)->state & SCTP_STATE_MASK) -#define SCTP_SET_STATE(asoc, newstate) ((asoc)->state = ((asoc)->state & ~SCTP_STATE_MASK) | newstate) -#define SCTP_CLEAR_SUBSTATE(asoc, substate) ((asoc)->state &= ~substate) -#define SCTP_ADD_SUBSTATE(asoc, substate) ((asoc)->state |= substate) +#define SCTP_GET_STATE(_stcb) \ + ((_stcb)->asoc.state & SCTP_STATE_MASK) +#define SCTP_SET_STATE(_stcb, _state) \ + sctp_set_state(_stcb, _state) +#define SCTP_CLEAR_SUBSTATE(_stcb, _substate) \ + (_stcb)->asoc.state &= ~(_substate) +#define SCTP_ADD_SUBSTATE(_stcb, _substate) \ + sctp_add_substate(_stcb, _substate) /* SCTP reachability state for each address */ #define SCTP_ADDR_REACHABLE 0x001 @@ -550,22 +537,17 @@ __FBSDID("$FreeBSD$"); #define SCTP_TIMER_TYPE_ASCONF 10 #define SCTP_TIMER_TYPE_SHUTDOWNGUARD 11 #define SCTP_TIMER_TYPE_AUTOCLOSE 12 -#define SCTP_TIMER_TYPE_EVENTWAKE 13 -#define SCTP_TIMER_TYPE_STRRESET 14 -#define SCTP_TIMER_TYPE_INPKILL 15 -#define SCTP_TIMER_TYPE_ASOCKILL 16 -#define SCTP_TIMER_TYPE_ADDR_WQ 17 -#define SCTP_TIMER_TYPE_ZERO_COPY 18 -#define SCTP_TIMER_TYPE_ZCOPY_SENDQ 19 -#define SCTP_TIMER_TYPE_PRIM_DELETED 20 +#define SCTP_TIMER_TYPE_STRRESET 13 +#define SCTP_TIMER_TYPE_INPKILL 14 +#define SCTP_TIMER_TYPE_ASOCKILL 15 +#define SCTP_TIMER_TYPE_ADDR_WQ 16 +#define SCTP_TIMER_TYPE_PRIM_DELETED 17 /* add new timers here - and increment LAST */ -#define SCTP_TIMER_TYPE_LAST 21 +#define SCTP_TIMER_TYPE_LAST 18 #define SCTP_IS_TIMER_TYPE_VALID(t) (((t) > SCTP_TIMER_TYPE_NONE) && \ ((t) < SCTP_TIMER_TYPE_LAST)) - - /* max number of TSN's dup'd that I will hold */ #define SCTP_MAX_DUP_TSNS 20 @@ -586,17 +568,6 @@ __FBSDID("$FreeBSD$"); */ #define SCTP_ASOC_MAX_CHUNKS_ON_QUEUE 512 - -/* The conversion from time to ticks and vice versa is done by rounding - * upwards. This way we can test in the code the time to be positive and - * know that this corresponds to a positive number of ticks. - */ -#define MSEC_TO_TICKS(x) ((hz == 1000) ? x : ((((x) * hz) + 999) / 1000)) -#define TICKS_TO_MSEC(x) ((hz == 1000) ? x : ((((x) * 1000) + (hz - 1)) / hz)) - -#define SEC_TO_TICKS(x) ((x) * hz) -#define TICKS_TO_SEC(x) (((x) + (hz - 1)) / hz) - /* * Basically the minimum amount of time before I do a early FR. Making this * value to low will cause duplicate retransmissions. @@ -627,8 +598,7 @@ __FBSDID("$FreeBSD$"); #define SCTP_RTO_LOWER_BOUND (1000) /* 1 sec is ms */ #define SCTP_RTO_INITIAL (3000) /* 3 sec in ms */ - -#define SCTP_INP_KILL_TIMEOUT 20/* number of ms to retry kill of inpcb */ +#define SCTP_INP_KILL_TIMEOUT 20 /* number of ms to retry kill of inpcb */ #define SCTP_ASOC_KILL_TIMEOUT 10 /* number of ms to retry kill of inpcb */ #define SCTP_DEF_MAX_INIT 8 @@ -638,7 +608,6 @@ __FBSDID("$FreeBSD$"); #define SCTP_DEF_PMTU_RAISE_SEC 600 /* 10 min between raise attempts */ - /* How many streams I request initially by default */ #define SCTP_OSTREAM_INITIAL 10 #define SCTP_ISTREAM_INITIAL 2048 @@ -717,7 +686,6 @@ __FBSDID("$FreeBSD$"); #define SCTP_NUMBER_OF_SECRETS 8 /* or 8 * 4 = 32 octets */ #define SCTP_SECRET_SIZE 32 /* number of octets in a 256 bits */ - /* * SCTP upper layer notifications */ @@ -758,7 +726,7 @@ __FBSDID("$FreeBSD$"); #define SCTP_DEFAULT_SPLIT_POINT_MIN 2904 /* Maximum length of diagnostic information in error causes */ -#define SCTP_DIAG_INFO_LEN 64 +#define SCTP_DIAG_INFO_LEN 128 /* ABORT CODES and other tell-tale location * codes are generated by adding the below @@ -776,9 +744,8 @@ __FBSDID("$FreeBSD$"); #define SCTP_FROM_SCTP_ASCONF 0x80000000 #define SCTP_FROM_SCTP_OUTPUT 0x90000000 #define SCTP_FROM_SCTP_PEELOFF 0xa0000000 -#define SCTP_FROM_SCTP_PANDA 0xb0000000 -#define SCTP_FROM_SCTP_SYSCTL 0xc0000000 -#define SCTP_FROM_SCTP_CC_FUNCTIONS 0xd0000000 +#define SCTP_FROM_SCTP_SYSCTL 0xb0000000 +#define SCTP_FROM_SCTP_CC_FUNCTIONS 0xc0000000 /* Location ID's */ #define SCTP_LOC_1 0x00000001 @@ -816,7 +783,8 @@ __FBSDID("$FreeBSD$"); #define SCTP_LOC_33 0x00000021 #define SCTP_LOC_34 0x00000022 #define SCTP_LOC_35 0x00000023 - +#define SCTP_LOC_36 0x00000024 +#define SCTP_LOC_37 0x00000025 /* Free assoc codes */ #define SCTP_NORMAL_PROC 0 @@ -836,7 +804,6 @@ __FBSDID("$FreeBSD$"); #define SCTP_DONOT_SETSCOPE 0 #define SCTP_DO_SETSCOPE 1 - /* This value determines the default for when * we try to add more on the send queue., if * there is room. This prevents us from cycling @@ -898,8 +865,9 @@ __FBSDID("$FreeBSD$"); #define SCTP_SSN_GE(a, b) SCTP_UINT16_GE(a, b) #define SCTP_TSN_GT(a, b) SCTP_UINT32_GT(a, b) #define SCTP_TSN_GE(a, b) SCTP_UINT32_GE(a, b) -#define SCTP_MSGID_GT(o, a, b) ((o == 1) ? SCTP_UINT16_GT((uint16_t)a, (uint16_t)b) : SCTP_UINT32_GT(a, b)) -#define SCTP_MSGID_GE(o, a, b) ((o == 1) ? SCTP_UINT16_GE((uint16_t)a, (uint16_t)b) : SCTP_UINT32_GE(a, b)) +#define SCTP_MID_GT(i, a, b) (((i) == 1) ? SCTP_UINT32_GT(a, b) : SCTP_UINT16_GT((uint16_t)a, (uint16_t)b)) +#define SCTP_MID_GE(i, a, b) (((i) == 1) ? SCTP_UINT32_GE(a, b) : SCTP_UINT16_GE((uint16_t)a, (uint16_t)b)) +#define SCTP_MID_EQ(i, a, b) (((i) == 1) ? a == b : (uint16_t)a == (uint16_t)b) /* Mapping array manipulation routines */ #define SCTP_IS_TSN_PRESENT(arry, gap) ((arry[(gap >> 3)] >> (gap & 0x07)) & 0x01) @@ -913,7 +881,6 @@ __FBSDID("$FreeBSD$"); } \ } while (0) - #define SCTP_RETRAN_DONE -1 #define SCTP_RETRAN_EXIT -2 @@ -964,15 +931,11 @@ __FBSDID("$FreeBSD$"); /*- * defines for socket lock states. - * Used by __APPLE__ and SCTP_SO_LOCK_TESTING + * Used by __APPLE__ */ #define SCTP_SO_LOCKED 1 #define SCTP_SO_NOT_LOCKED 0 - -#define SCTP_HOLDS_LOCK 1 -#define SCTP_NOT_LOCKED 0 - /*- * For address locks, do we hold the lock? */ @@ -994,6 +957,8 @@ __FBSDID("$FreeBSD$"); ((((uint8_t *)&(a)->s_addr)[0] == 169) && \ (((uint8_t *)&(a)->s_addr)[1] == 254)) +/* Maximum size of optval for IPPROTO_SCTP level socket options. */ +#define SCTP_SOCKET_OPTION_LIMIT (64 * 1024) #if defined(_KERNEL) #define SCTP_GETTIME_TIMEVAL(x) (getmicrouptime(x)) @@ -1013,7 +978,7 @@ do { \ #define sctp_sowwakeup_locked(inp, so) \ do { \ if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \ - SOCKBUF_UNLOCK(&((so)->so_snd)); \ + SOCKBUF_UNLOCK(&((so)->so_snd)); \ inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEOUTPUT; \ } else { \ sowwakeup_locked(so); \ @@ -1033,7 +998,7 @@ do { \ do { \ if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { \ inp->sctp_flags |= SCTP_PCB_FLAGS_WAKEINPUT; \ - SOCKBUF_UNLOCK(&((so)->so_rcv)); \ + SOCKBUF_UNLOCK(&((so)->so_rcv)); \ } else { \ sorwakeup_locked(so); \ } \ diff --git a/tools/compat/include/netinet/sctp_uio.h b/tools/compat/include/netinet/sctp_uio.h index 6b09c28b6..bd33a5502 100644 --- a/tools/compat/include/netinet/sctp_uio.h +++ b/tools/compat/include/netinet/sctp_uio.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. @@ -36,8 +38,7 @@ __FBSDID("$FreeBSD$"); #ifndef _NETINET_SCTP_UIO_H_ #define _NETINET_SCTP_UIO_H_ - -#if ! defined(_KERNEL) +#if !defined(_KERNEL) #include #endif #include @@ -109,7 +110,6 @@ struct sctp_initmsg { * all sendrcvinfo's need a verfid for SENDING only. */ - #define SCTP_ALIGN_RESV_PAD 92 #define SCTP_ALIGN_RESV_PAD_SHORT 76 @@ -147,7 +147,6 @@ struct sctp_extrcvinfo { uint16_t sinfo_keynumber_valid; uint8_t __reserve_pad[SCTP_ALIGN_RESV_PAD_SHORT]; }; - #define sinfo_pr_value sinfo_timetolive #define sreinfo_next_flags serinfo_next_flags #define sreinfo_next_stream serinfo_next_stream @@ -257,13 +256,14 @@ struct sctp_snd_all_completes { /* for the endpoint */ /* The lower four bits is an enumeration of PR-SCTP policies */ -#define SCTP_PR_SCTP_NONE 0x0000/* Reliable transfer */ -#define SCTP_PR_SCTP_TTL 0x0001/* Time based PR-SCTP */ -#define SCTP_PR_SCTP_PRIO 0x0002/* Buffer based PR-SCTP */ +#define SCTP_PR_SCTP_NONE 0x0000 /* Reliable transfer */ +#define SCTP_PR_SCTP_TTL 0x0001 /* Time based PR-SCTP */ +#define SCTP_PR_SCTP_PRIO 0x0002 /* Buffer based PR-SCTP */ #define SCTP_PR_SCTP_BUF SCTP_PR_SCTP_PRIO /* For backwards compatibility */ -#define SCTP_PR_SCTP_RTX 0x0003/* Number of retransmissions based PR-SCTP */ +#define SCTP_PR_SCTP_RTX 0x0003 /* Number of retransmissions based + * PR-SCTP */ #define SCTP_PR_SCTP_MAX SCTP_PR_SCTP_RTX -#define SCTP_PR_SCTP_ALL 0x000f/* Used for aggregated stats */ +#define SCTP_PR_SCTP_ALL 0x000f /* Used for aggregated stats */ #define PR_SCTP_POLICY(x) ((x) & 0x0f) #define PR_SCTP_ENABLED(x) ((PR_SCTP_POLICY(x) != SCTP_PR_SCTP_NONE) && \ @@ -422,7 +422,6 @@ struct sctp_setadaption { uint32_t ssb_adaption_ind; }; - /* * Partial Delivery API event */ @@ -439,7 +438,6 @@ struct sctp_pdapi_event { /* indication values */ #define SCTP_PARTIAL_DELIVERY_ABORTED 0x0001 - /* * authentication key event */ @@ -459,7 +457,6 @@ struct sctp_authkey_event { #define SCTP_AUTH_NO_AUTH 0x0002 #define SCTP_AUTH_FREE_KEY 0x0003 - struct sctp_sender_dry_event { uint16_t sender_dry_type; uint16_t sender_dry_flags; @@ -467,7 +464,6 @@ struct sctp_sender_dry_event { sctp_assoc_t sender_dry_assoc_id; }; - /* * Stream reset event - subscribe to SCTP_STREAM_RESET_EVENT */ @@ -515,7 +511,6 @@ struct sctp_stream_change_event { #define SCTP_STREAM_CHANGE_DENIED 0x0004 #define SCTP_STREAM_CHANGE_FAILED 0x0008 - /* SCTP notification event */ struct sctp_tlv { uint16_t sn_type; @@ -573,7 +568,6 @@ struct sctp_paddrparams { uint16_t spp_pathmaxrxt; uint8_t spp_dscp; }; - #define spp_ipv4_tos spp_dscp #define SPP_HB_ENABLE 0x00000001 @@ -632,10 +626,15 @@ struct sctp_setpeerprim { uint8_t sspp_padding[4]; }; +union sctp_sockstore { + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + struct sockaddr sa; +}; + struct sctp_getaddresses { sctp_assoc_t sget_assoc_id; - /* addr is filled in for N * sockaddr_storage */ - struct sockaddr addr[1]; + union sctp_sockstore addr[]; }; struct sctp_status { @@ -744,7 +743,7 @@ struct sctp_prstatus { struct sctp_cwnd_args { struct sctp_nets *net; /* network to *//* FIXME: LP64 issue */ - uint32_t cwnd_new_value;/* cwnd in k */ + uint32_t cwnd_new_value; /* cwnd in k */ uint32_t pseudo_cumack; uint16_t inflight; /* flightsize in k */ uint16_t cwnd_augment; /* increment to it */ @@ -758,9 +757,9 @@ struct sctp_blk_args { uint32_t onsb; /* in 1k bytes */ uint32_t sndlen; /* len of send being attempted */ uint32_t peer_rwnd; /* rwnd of peer */ - uint16_t send_sent_qcnt;/* chnk cnt */ + uint16_t send_sent_qcnt; /* chnk cnt */ uint16_t stream_qcnt; /* chnk cnt */ - uint16_t chunks_on_oque;/* chunks out */ + uint16_t chunks_on_oque; /* chunks out */ uint16_t flight_size; /* flight size in k */ }; @@ -952,7 +951,7 @@ struct sctpstat { uint32_t sctps_collisionestab; uint32_t sctps_passiveestab; /* sctpStats 3 (Counter32) */ uint32_t sctps_aborted; /* sctpStats 4 (Counter32) */ - uint32_t sctps_shutdown;/* sctpStats 5 (Counter32) */ + uint32_t sctps_shutdown; /* sctpStats 5 (Counter32) */ uint32_t sctps_outoftheblue; /* sctpStats 6 (Counter32) */ uint32_t sctps_checksumerrors; /* sctpStats 7 (Counter32) */ uint32_t sctps_outcontrolchunks; /* sctpStats 8 (Counter64) */ @@ -971,12 +970,12 @@ struct sctpstat { uint32_t sctps_recvdatagrams; /* total input datagrams */ uint32_t sctps_recvpktwithdata; /* total packets that had data */ uint32_t sctps_recvsacks; /* total input SACK chunks */ - uint32_t sctps_recvdata;/* total input DATA chunks */ + uint32_t sctps_recvdata; /* total input DATA chunks */ uint32_t sctps_recvdupdata; /* total input duplicate DATA chunks */ uint32_t sctps_recvheartbeat; /* total input HB chunks */ uint32_t sctps_recvheartbeatack; /* total input HB-ACK chunks */ - uint32_t sctps_recvecne;/* total input ECNE chunks */ - uint32_t sctps_recvauth;/* total input AUTH chunks */ + uint32_t sctps_recvecne; /* total input ECNE chunks */ + uint32_t sctps_recvauth; /* total input AUTH chunks */ uint32_t sctps_recvauthmissing; /* total input chunks missing AUTH */ uint32_t sctps_recvivalhmacid; /* total number of invalid HMAC ids * received */ @@ -986,14 +985,14 @@ struct sctpstat { uint32_t sctps_recvexpress; /* total fast path receives all one * chunk */ uint32_t sctps_recvexpressm; /* total fast path multi-part data */ - uint32_t sctps_recvnocrc; + uint32_t sctps_recv_spare; /* formerly sctps_recvnocrc */ uint32_t sctps_recvswcrc; uint32_t sctps_recvhwcrc; /* output statistics: */ uint32_t sctps_sendpackets; /* total output packets */ uint32_t sctps_sendsacks; /* total output SACKs */ - uint32_t sctps_senddata;/* total output DATA chunks */ + uint32_t sctps_senddata; /* total output DATA chunks */ uint32_t sctps_sendretransdata; /* total output retransmitted DATA * chunks */ uint32_t sctps_sendfastretrans; /* total output fast retransmitted @@ -1003,17 +1002,17 @@ struct sctpstat { * chunk (u-del multi-fr * algo). */ uint32_t sctps_sendheartbeat; /* total output HB chunks */ - uint32_t sctps_sendecne;/* total output ECNE chunks */ - uint32_t sctps_sendauth;/* total output AUTH chunks FIXME */ + uint32_t sctps_sendecne; /* total output ECNE chunks */ + uint32_t sctps_sendauth; /* total output AUTH chunks FIXME */ uint32_t sctps_senderrors; /* ip_output error counter */ - uint32_t sctps_sendnocrc; + uint32_t sctps_send_spare; /* formerly sctps_sendnocrc */ uint32_t sctps_sendswcrc; uint32_t sctps_sendhwcrc; /* PCKDROPREP statistics: */ uint32_t sctps_pdrpfmbox; /* Packet drop from middle box */ uint32_t sctps_pdrpfehos; /* P-drop from end host */ - uint32_t sctps_pdrpmbda;/* P-drops with data */ - uint32_t sctps_pdrpmbct;/* P-drops, non-data, non-endhost */ + uint32_t sctps_pdrpmbda; /* P-drops with data */ + uint32_t sctps_pdrpmbct; /* P-drops, non-data, non-endhost */ uint32_t sctps_pdrpbwrpt; /* P-drop, non-endhost, bandwidth rep * only */ uint32_t sctps_pdrpcrupt; /* P-drop, not enough for chunk header */ @@ -1024,16 +1023,17 @@ struct sctpstat { uint32_t sctps_pdrpdnfnd; /* P-drop, attempt reverse TSN lookup */ uint32_t sctps_pdrpdiwnp; /* P-drop, e-host confirms zero-rwnd */ uint32_t sctps_pdrpdizrw; /* P-drop, midbox confirms no space */ - uint32_t sctps_pdrpbadd;/* P-drop, data did not match TSN */ - uint32_t sctps_pdrpmark;/* P-drop, TSN's marked for Fast Retran */ + uint32_t sctps_pdrpbadd; /* P-drop, data did not match TSN */ + uint32_t sctps_pdrpmark; /* P-drop, TSN's marked for Fast + * Retran */ /* timeouts */ uint32_t sctps_timoiterator; /* Number of iterator timers that * fired */ - uint32_t sctps_timodata;/* Number of T3 data time outs */ + uint32_t sctps_timodata; /* Number of T3 data time outs */ uint32_t sctps_timowindowprobe; /* Number of window probe (T3) timers * that fired */ - uint32_t sctps_timoinit;/* Number of INIT timers that fired */ - uint32_t sctps_timosack;/* Number of sack timers that fired */ + uint32_t sctps_timoinit; /* Number of INIT timers that fired */ + uint32_t sctps_timosack; /* Number of sack timers that fired */ uint32_t sctps_timoshutdown; /* Number of shutdown timers that * fired */ uint32_t sctps_timoheartbeat; /* Number of heartbeat timers that @@ -1126,7 +1126,7 @@ struct sctpstat { #define SCTP_STAT_INCR(_x) SCTP_STAT_INCR_BY(_x,1) #define SCTP_STAT_DECR(_x) SCTP_STAT_DECR_BY(_x,1) -#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT) +#if defined(SMP) && defined(SCTP_USE_PERCPU_STAT) #define SCTP_STAT_INCR_BY(_x,_d) (SCTP_BASE_STATS[PCPU_GET(cpuid)]._x += _d) #define SCTP_STAT_DECR_BY(_x,_d) (SCTP_BASE_STATS[PCPU_GET(cpuid)]._x -= _d) #else @@ -1141,13 +1141,6 @@ struct sctpstat { #define SCTP_STAT_DECR_COUNTER64(_x) SCTP_STAT_DECR(_x) #define SCTP_STAT_DECR_GAUGE32(_x) SCTP_STAT_DECR(_x) -union sctp_sockstore { - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - struct sockaddr sa; -}; - - /***********************************/ /* And something for us old timers */ /***********************************/ @@ -1163,7 +1156,6 @@ union sctp_sockstore { #endif /***********************************/ - struct xsctp_inpcb { uint32_t last; uint32_t flags; @@ -1175,14 +1167,11 @@ struct xsctp_inpcb { uint16_t local_port; uint16_t qlen_old; uint16_t maxqlen_old; - void *socket; + uint16_t __spare16; + kvaddr_t socket; uint32_t qlen; uint32_t maxqlen; -#if defined(__LP64__) - uint32_t extra_padding[27]; /* future */ -#else - uint32_t extra_padding[28]; /* future */ -#endif + uint32_t extra_padding[26]; /* future */ }; struct xsctp_tcb { @@ -1192,7 +1181,7 @@ struct xsctp_tcb { uint32_t state; /* sctpAssocEntry 8 */ uint32_t in_streams; /* sctpAssocEntry 9 */ uint32_t out_streams; /* sctpAssocEntry 10 */ - uint32_t max_nr_retrans;/* sctpAssocEntry 11 */ + uint32_t max_nr_retrans; /* sctpAssocEntry 11 */ uint32_t primary_process; /* sctpAssocEntry 12 */ uint32_t T1_expireries; /* sctpAssocEntry 13 */ uint32_t T2_expireries; /* sctpAssocEntry 14 */ @@ -1241,7 +1230,9 @@ struct xsctp_raddr { uint32_t rtt; uint32_t heartbeat_interval; uint32_t ssthresh; - uint32_t extra_padding[30]; /* future */ + uint16_t encaps_port; + uint16_t state; + uint32_t extra_padding[29]; /* future */ }; #define SCTP_MAX_LOGGING_SIZE 30000 @@ -1284,7 +1275,6 @@ sctp_sorecvmsg(struct socket *so, int *msg_flags, struct sctp_sndrcvinfo *sinfo, int filling_sinfo); - #endif /* @@ -1304,37 +1294,37 @@ void sctp_freeladdrs(struct sockaddr *); int sctp_opt_info(int, sctp_assoc_t, int, void *, socklen_t *); /* deprecated */ -ssize_t +ssize_t sctp_sendmsg(int, const void *, size_t, const struct sockaddr *, socklen_t, uint32_t, uint32_t, uint16_t, uint32_t, uint32_t); /* deprecated */ -ssize_t +ssize_t sctp_send(int, const void *, size_t, const struct sctp_sndrcvinfo *, int); /* deprecated */ -ssize_t +ssize_t sctp_sendx(int, const void *, size_t, struct sockaddr *, int, struct sctp_sndrcvinfo *, int); /* deprecated */ -ssize_t +ssize_t sctp_sendmsgx(int sd, const void *, size_t, struct sockaddr *, int, uint32_t, uint32_t, uint16_t, uint32_t, uint32_t); sctp_assoc_t sctp_getassocid(int, struct sockaddr *); /* deprecated */ -ssize_t +ssize_t sctp_recvmsg(int, void *, size_t, struct sockaddr *, socklen_t *, struct sctp_sndrcvinfo *, int *); -ssize_t +ssize_t sctp_sendv(int, const struct iovec *, int, struct sockaddr *, int, void *, socklen_t, unsigned int, int); -ssize_t +ssize_t sctp_recvv(int, const struct iovec *, int, struct sockaddr *, socklen_t *, void *, socklen_t *, unsigned int *, int *); diff --git a/tools/compat/include/netinet/tcp.h b/tools/compat/include/netinet/tcp.h index 470381040..0b71bd465 100644 --- a/tools/compat/include/netinet/tcp.h +++ b/tools/compat/include/netinet/tcp.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -69,14 +71,17 @@ struct tcphdr { #define TH_URG 0x20 #define TH_ECE 0x40 #define TH_CWR 0x80 +#define TH_AE 0x100 /* maps into th_x2 */ #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|TH_ECE|TH_CWR) -#define PRINT_TH_FLAGS "\20\1FIN\2SYN\3RST\4PUSH\5ACK\6URG\7ECE\10CWR" +#define PRINT_TH_FLAGS "\20\1FIN\2SYN\3RST\4PUSH\5ACK\6URG\7ECE\10CWR\11AE" u_short th_win; /* window */ u_short th_sum; /* checksum */ u_short th_urp; /* urgent pointer */ }; +#define PADTCPOLEN(len) ((((len) / 4) + !!((len) % 4)) * 4) + #define TCPOPT_EOL 0 #define TCPOLEN_EOL 1 #define TCPOPT_PAD 0 /* padding after EOL */ @@ -99,14 +104,11 @@ struct tcphdr { #define TCPOLEN_SIGNATURE 18 #define TCPOPT_FAST_OPEN 34 #define TCPOLEN_FAST_OPEN_EMPTY 2 -#define TCPOLEN_FAST_OPEN_MIN 6 -#define TCPOLEN_FAST_OPEN_MAX 18 /* Miscellaneous constants */ #define MAX_SACK_BLKS 6 /* Max # SACK blocks stored at receiver side */ #define TCP_MAX_SACK 4 /* MAX # SACKs sent in any segment */ - /* * The default maximum segment size (MSS) to be used for new TCP connections * when path MTU discovery is not enabled. @@ -150,6 +152,10 @@ struct tcphdr { #define TCP_MAXHLEN (0xf<<2) /* max length of header in bytes */ #define TCP_MAXOLEN (TCP_MAXHLEN - sizeof(struct tcphdr)) /* max space left for options */ + +#define TCP_FASTOPEN_MIN_COOKIE_LEN 4 /* Per RFC7413 */ +#define TCP_FASTOPEN_MAX_COOKIE_LEN 16 /* Per RFC7413 */ +#define TCP_FASTOPEN_PSK_LEN 16 /* Same as TCP_FASTOPEN_KEY_LEN */ #endif /* __BSD_VISIBLE */ /* @@ -164,8 +170,23 @@ struct tcphdr { #define TCP_NOOPT 8 /* don't use TCP options */ #define TCP_MD5SIG 16 /* use MD5 digests (RFC2385) */ #define TCP_INFO 32 /* retrieve tcp_info structure */ +#define TCP_STATS 33 /* retrieve stats blob structure */ +#define TCP_LOG 34 /* configure event logging for connection */ +#define TCP_LOGBUF 35 /* retrieve event log for connection */ +#define TCP_LOGID 36 /* configure log ID to correlate connections */ +#define TCP_LOGDUMP 37 /* dump connection log events to device */ +#define TCP_LOGDUMPID 38 /* dump events from connections with same ID to + device */ +#define TCP_TXTLS_ENABLE 39 /* TLS framing and encryption for transmit */ +#define TCP_TXTLS_MODE 40 /* Transmit TLS mode */ +#define TCP_RXTLS_ENABLE 41 /* TLS framing and encryption for receive */ +#define TCP_RXTLS_MODE 42 /* Receive TLS mode */ #define TCP_CONGESTION 64 /* get/set congestion control algorithm */ #define TCP_CCALGOOPT 65 /* get/set cc algorithm specific options */ +#define TCP_DELACK 72 /* socket option for delayed ack */ +#define TCP_FIN_IS_RST 73 /* A fin from the peer is treated has a RST */ +#define TCP_LOG_LIMIT 74 /* Limit to number of records in tcp-log */ +#define TCP_SHARED_CWND_ALLOWED 75 /* Use of a shared cwnd is allowed */ #define TCP_KEEPINIT 128 /* N, time to establish connection */ #define TCP_KEEPIDLE 256 /* L,N,X start keeplives after this period */ #define TCP_KEEPINTVL 512 /* L,N interval between keepalives */ @@ -174,6 +195,95 @@ struct tcphdr { #define TCP_PCAP_OUT 2048 /* number of output packets to keep */ #define TCP_PCAP_IN 4096 /* number of input packets to keep */ #define TCP_FUNCTION_BLK 8192 /* Set the tcp function pointers to the specified stack */ +/* Options for Rack and BBR */ +#define TCP_REUSPORT_LB_NUMA 1026 /* set listen socket numa domain */ +#define TCP_RACK_MBUF_QUEUE 1050 /* Do we allow mbuf queuing if supported */ +#define TCP_RACK_PROP 1051 /* RACK proportional rate reduction (bool) */ +#define TCP_RACK_TLP_REDUCE 1052 /* RACK TLP cwnd reduction (bool) */ +#define TCP_RACK_PACE_REDUCE 1053 /* RACK Pacing reduction factor (divisor) */ +#define TCP_RACK_PACE_MAX_SEG 1054 /* Max TSO size we will send */ +#define TCP_RACK_PACE_ALWAYS 1055 /* Use the always pace method */ +#define TCP_RACK_PROP_RATE 1056 /* The proportional reduction rate */ +#define TCP_RACK_PRR_SENDALOT 1057 /* Allow PRR to send more than one seg */ +#define TCP_RACK_MIN_TO 1058 /* Minimum time between rack t-o's in ms */ +#define TCP_RACK_EARLY_RECOV 1059 /* Should recovery happen early (bool) */ +#define TCP_RACK_EARLY_SEG 1060 /* If early recovery max segments */ +#define TCP_RACK_REORD_THRESH 1061 /* RACK reorder threshold (shift amount) */ +#define TCP_RACK_REORD_FADE 1062 /* Does reordering fade after ms time */ +#define TCP_RACK_TLP_THRESH 1063 /* RACK TLP theshold i.e. srtt+(srtt/N) */ +#define TCP_RACK_PKT_DELAY 1064 /* RACK added ms i.e. rack-rtt + reord + N */ +#define TCP_RACK_TLP_INC_VAR 1065 /* Does TLP include rtt variance in t-o */ +#define TCP_BBR_IWINTSO 1067 /* Initial TSO window for BBRs first sends */ +#define TCP_BBR_RECFORCE 1068 /* Enter recovery force out a segment disregard pacer no longer valid */ +#define TCP_BBR_STARTUP_PG 1069 /* Startup pacing gain */ +#define TCP_BBR_DRAIN_PG 1070 /* Drain pacing gain */ +#define TCP_BBR_RWND_IS_APP 1071 /* Rwnd limited is considered app limited */ +#define TCP_BBR_PROBE_RTT_INT 1072 /* How long in useconds between probe-rtt */ +#define TCP_BBR_ONE_RETRAN 1073 /* Is only one segment allowed out during retran */ +#define TCP_BBR_STARTUP_LOSS_EXIT 1074 /* Do we exit a loss during startup if not 20% incr */ +#define TCP_BBR_USE_LOWGAIN 1075 /* lower the gain in PROBE_BW enable */ +#define TCP_BBR_LOWGAIN_THRESH 1076 /* Unused after 2.3 morphs to TSLIMITS >= 2.3 */ +#define TCP_BBR_TSLIMITS 1076 /* Do we use experimental Timestamp limiting for our algo */ +#define TCP_BBR_LOWGAIN_HALF 1077 /* Unused after 2.3 */ +#define TCP_BBR_PACE_OH 1077 /* Reused in 4.2 for pacing overhead setting */ +#define TCP_BBR_LOWGAIN_FD 1078 /* Unused after 2.3 */ +#define TCP_BBR_HOLD_TARGET 1078 /* For 4.3 on */ +#define TCP_BBR_USEDEL_RATE 1079 /* Enable use of delivery rate for loss recovery */ +#define TCP_BBR_MIN_RTO 1080 /* Min RTO in milliseconds */ +#define TCP_BBR_MAX_RTO 1081 /* Max RTO in milliseconds */ +#define TCP_BBR_REC_OVER_HPTS 1082 /* Recovery override htps settings 0/1/3 */ +#define TCP_BBR_UNLIMITED 1083 /* Not used before 2.3 and morphs to algorithm >= 2.3 */ +#define TCP_BBR_ALGORITHM 1083 /* What measurement algo does BBR use netflix=0, google=1 */ +#define TCP_BBR_DRAIN_INC_EXTRA 1084 /* Does the 3/4 drain target include the extra gain */ +#define TCP_BBR_STARTUP_EXIT_EPOCH 1085 /* what epoch gets us out of startup */ +#define TCP_BBR_PACE_PER_SEC 1086 +#define TCP_BBR_PACE_DEL_TAR 1087 +#define TCP_BBR_PACE_SEG_MAX 1088 +#define TCP_BBR_PACE_SEG_MIN 1089 +#define TCP_BBR_PACE_CROSS 1090 +#define TCP_RACK_IDLE_REDUCE_HIGH 1092 /* Reduce the highest cwnd seen to IW on idle */ +#define TCP_RACK_MIN_PACE 1093 /* Do we enforce rack min pace time */ +#define TCP_RACK_MIN_PACE_SEG 1094 /* If so what is the seg threshould */ +#define TCP_RACK_GP_INCREASE 1094 /* After 4.1 its the GP increase in older rack */ +#define TCP_RACK_TLP_USE 1095 +#define TCP_BBR_ACK_COMP_ALG 1096 /* Not used */ +#define TCP_BBR_TMR_PACE_OH 1096 /* Recycled in 4.2 */ +#define TCP_BBR_EXTRA_GAIN 1097 +#define TCP_RACK_DO_DETECTION 1097 /* Recycle of extra gain for rack, attack detection */ +#define TCP_BBR_RACK_RTT_USE 1098 /* what RTT should we use 0, 1, or 2? */ +#define TCP_BBR_RETRAN_WTSO 1099 +#define TCP_DATA_AFTER_CLOSE 1100 +#define TCP_BBR_PROBE_RTT_GAIN 1101 +#define TCP_BBR_PROBE_RTT_LEN 1102 +#define TCP_BBR_SEND_IWND_IN_TSO 1103 /* Do we burst out whole iwin size chunks at start? */ +#define TCP_BBR_USE_RACK_RR 1104 /* Do we use the rack rapid recovery for pacing rxt's */ +#define TCP_BBR_USE_RACK_CHEAT TCP_BBR_USE_RACK_RR /* Compat. */ +#define TCP_BBR_HDWR_PACE 1105 /* Enable/disable hardware pacing */ +#define TCP_BBR_UTTER_MAX_TSO 1106 /* Do we enforce an utter max TSO size */ +#define TCP_BBR_EXTRA_STATE 1107 /* Special exit-persist catch up */ +#define TCP_BBR_FLOOR_MIN_TSO 1108 /* The min tso size */ +#define TCP_BBR_MIN_TOPACEOUT 1109 /* Do we suspend pacing until */ +#define TCP_BBR_TSTMP_RAISES 1110 /* Can a timestamp measurement raise the b/w */ +#define TCP_BBR_POLICER_DETECT 1111 /* Turn on/off google mode policer detection */ +#define TCP_BBR_RACK_INIT_RATE 1112 /* Set an initial pacing rate for when we have no b/w in kbits per sec */ +#define TCP_RACK_RR_CONF 1113 /* Rack rapid recovery configuration control*/ +#define TCP_RACK_CHEAT_NOT_CONF_RATE TCP_RACK_RR_CONF +#define TCP_RACK_GP_INCREASE_CA 1114 /* GP increase for Congestion Avoidance */ +#define TCP_RACK_GP_INCREASE_SS 1115 /* GP increase for Slow Start */ +#define TCP_RACK_GP_INCREASE_REC 1116 /* GP increase for Recovery */ +#define TCP_RACK_FORCE_MSEG 1117 /* Override to use the user set max-seg value */ +#define TCP_RACK_PACE_RATE_CA 1118 /* Pacing rate for Congestion Avoidance */ +#define TCP_RACK_PACE_RATE_SS 1119 /* Pacing rate for Slow Start */ +#define TCP_RACK_PACE_RATE_REC 1120 /* Pacing rate for Recovery */ +#define TCP_NO_PRR 1122 /* If pacing, don't use prr */ +#define TCP_RACK_NONRXT_CFG_RATE 1123 /* In recovery does a non-rxt use the cfg rate */ +#define TCP_SHARED_CWND_ENABLE 1124 /* Use a shared cwnd if allowed */ +#define TCP_TIMELY_DYN_ADJ 1125 /* Do we attempt dynamic multipler adjustment with timely. */ +#define TCP_RACK_NO_PUSH_AT_MAX 1126 /* For timely do not push if we are over max rtt */ +#define TCP_RACK_PACE_TO_FILL 1127 /* If we are not in recovery, always pace to fill the cwnd in 1 RTT */ +#define TCP_SHARED_CWND_TIME_LIMIT 1128 /* we should limit to low time values the scwnd life */ +#define TCP_RACK_PROFILE 1129 /* Select a profile that sets multiple options */ + /* Start of reserved space for third-party user-settable options. */ #define TCP_VENDOR SO_VENDOR @@ -185,6 +295,9 @@ struct tcphdr { #define TCPI_OPT_ECN 0x08 #define TCPI_OPT_TOE 0x10 +/* Maximum length of log ID. */ +#define TCP_LOG_ID_LEN 64 + /* * The TCP_INFO socket option comes from the Linux 2.6 TCP API, and permits * the caller to query certain information about the state of a TCP @@ -246,10 +359,20 @@ struct tcp_info { u_int32_t tcpi_snd_rexmitpack; /* Retransmitted packets */ u_int32_t tcpi_rcv_ooopack; /* Out-of-order packets */ u_int32_t tcpi_snd_zerowin; /* Zero-sized windows sent */ - + /* Padding to grow without breaking ABI. */ u_int32_t __tcpi_pad[26]; /* Padding. */ }; + +/* + * If this structure is provided when setting the TCP_FASTOPEN socket + * option, and the enable member is non-zero, a subsequent connect will use + * pre-shared key (PSK) mode using the provided key. + */ +struct tcp_fastopen { + int enable; + uint8_t psk[TCP_FASTOPEN_PSK_LEN]; +}; #endif #define TCP_FUNCTION_NAME_LEN_MAX 32 @@ -258,4 +381,33 @@ struct tcp_function_set { uint32_t pcbcnt; }; +/* TLS modes for TCP_TXTLS_MODE */ +#define TCP_TLS_MODE_NONE 0 +#define TCP_TLS_MODE_SW 1 +#define TCP_TLS_MODE_IFNET 2 +#define TCP_TLS_MODE_TOE 3 + +/* + * TCP Control message types + */ +#define TLS_SET_RECORD_TYPE 1 +#define TLS_GET_RECORD 2 + +/* + * TCP specific variables of interest for tp->t_stats stats(9) accounting. + */ +#define VOI_TCP_TXPB 0 /* Transmit payload bytes */ +#define VOI_TCP_RETXPB 1 /* Retransmit payload bytes */ +#define VOI_TCP_FRWIN 2 /* Foreign receive window */ +#define VOI_TCP_LCWIN 3 /* Local congesiton window */ +#define VOI_TCP_RTT 4 /* Round trip time */ +#define VOI_TCP_CSIG 5 /* Congestion signal */ +#define VOI_TCP_GPUT 6 /* Goodput */ +#define VOI_TCP_CALCFRWINDIFF 7 /* Congestion avoidance LCWIN - FRWIN */ +#define VOI_TCP_GPUT_ND 8 /* Goodput normalised delta */ +#define VOI_TCP_ACKLEN 9 /* Average ACKed bytes per ACK */ + +#define TCP_REUSPORT_LB_NUMA_NODOM (-2) /* remove numa binding */ +#define TCP_REUSPORT_LB_NUMA_CURDOM (-1) /* bind to current domain */ + #endif /* !_NETINET_TCP_H_ */ diff --git a/tools/compat/include/netinet/tcp_fsm.h b/tools/compat/include/netinet/tcp_fsm.h index 61fd0c1f8..8bd129f61 100644 --- a/tools/compat/include/netinet/tcp_fsm.h +++ b/tools/compat/include/netinet/tcp_fsm.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. * All rights reserved. @@ -11,7 +13,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -73,7 +75,8 @@ #define TCPS_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED) #define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED) -#define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT) +#define TCPS_HAVERCVDFIN(s) \ + ((s) == TCPS_CLOSE_WAIT || ((s) >= TCPS_CLOSING && (s) != TCPS_FIN_WAIT_2)) #ifdef TCPOUTFLAGS /* @@ -94,7 +97,7 @@ static u_char tcp_outflags[TCP_NSTATES] = { TH_FIN|TH_ACK, /* 8, LAST_ACK */ TH_ACK, /* 9, FIN_WAIT_2 */ TH_ACK, /* 10, TIME_WAIT */ -}; +}; #endif #ifdef KPROF diff --git a/tools/compat/include/netinet/tcp_seq.h b/tools/compat/include/netinet/tcp_seq.h index 51d971f22..b6e682ec1 100644 --- a/tools/compat/include/netinet/tcp_seq.h +++ b/tools/compat/include/netinet/tcp_seq.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993, 1995 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -45,6 +47,14 @@ #define SEQ_MIN(a, b) ((SEQ_LT(a, b)) ? (a) : (b)) #define SEQ_MAX(a, b) ((SEQ_GT(a, b)) ? (a) : (b)) +#define WIN_LT(a,b) (ntohs(a) < ntohs(b)) +#define WIN_LEQ(a,b) (ntohs(a) <= ntohs(b)) +#define WIN_GT(a,b) (ntohs(a) > ntohs(b)) +#define WIN_GEQ(a,b) (ntohs(a) >= ntohs(b)) + +#define WIN_MIN(a, b) ((WIN_LT(a, b)) ? (a) : (b)) +#define WIN_MAX(a, b) ((WIN_GT(a, b)) ? (a) : (b)) + /* for modulo comparisons of timestamps */ #define TSTMP_LT(a,b) ((int)((a)-(b)) < 0) #define TSTMP_GT(a,b) ((int)((a)-(b)) > 0) @@ -75,20 +85,17 @@ * tcp_ts_getticks() in ms, should be 1ms < x < 1000ms according to RFC 1323. * We always use 1ms granularity independent of hz. */ -static __inline u_int +static __inline uint32_t tcp_ts_getticks(void) { struct timeval tv; - u_long ms; /* * getmicrouptime() should be good enough for any 1-1000ms granularity. * Do not use getmicrotime() here as it might break nfsroot/tcp. */ getmicrouptime(&tv); - ms = tv.tv_sec * 1000 + tv.tv_usec / 1000; - - return (ms); + return (tv.tv_sec * 1000 + tv.tv_usec / 1000); } #endif /* _KERNEL */ diff --git a/tools/compat/include/netinet/tcp_timer.h b/tools/compat/include/netinet/tcp_timer.h index 12481b570..6f0c3a466 100644 --- a/tools/compat/include/netinet/tcp_timer.h +++ b/tools/compat/include/netinet/tcp_timer.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -75,7 +77,7 @@ #define TCPTV_MSL ( 30*hz) /* max seg lifetime (hah!) */ #define TCPTV_SRTTBASE 0 /* base roundtrip time; if 0, no idea yet */ -#define TCPTV_RTOBASE ( 3*hz) /* assumed RTO if no info */ +#define TCPTV_RTOBASE ( 1*hz) /* assumed RTO if no info */ #define TCPTV_PERSMIN ( 5*hz) /* minimum persist interval */ #define TCPTV_PERSMAX ( 60*hz) /* maximum persist interval */ @@ -117,7 +119,14 @@ #define TCP_MAXRXTSHIFT 12 /* maximum retransmits */ -#define TCPTV_DELACK ( hz/10 ) /* 100ms timeout */ +#define TCPTV_DELACK ( hz/25 ) /* 40ms timeout */ + +/* + * If we exceed this number of retransmits for a single segment, we'll consider + * the current srtt measurement no longer valid and will recalculate from + * scratch starting with the next ACK. + */ +#define TCP_RTT_INVALIDATE (TCP_MAXRXTSHIFT / 4) #ifdef TCPTIMERS static const char *tcptimers[] = @@ -159,11 +168,15 @@ struct tcp_timer { #define TT_2MSL 0x0010 #define TT_MASK (TT_DELACK|TT_REXMT|TT_PERSIST|TT_KEEP|TT_2MSL) -#define TT_DELACK_RST 0x0100 -#define TT_REXMT_RST 0x0200 -#define TT_PERSIST_RST 0x0400 -#define TT_KEEP_RST 0x0800 -#define TT_2MSL_RST 0x1000 +/* + * Suspend flags - used when suspending a timer + * from ever running again. + */ +#define TT_DELACK_SUS 0x0100 +#define TT_REXMT_SUS 0x0200 +#define TT_PERSIST_SUS 0x0400 +#define TT_KEEP_SUS 0x0800 +#define TT_2MSL_SUS 0x1000 #define TT_STOPPED 0x00010000 @@ -181,16 +194,29 @@ extern int tcp_keepintvl; /* time between keepalive probes */ extern int tcp_keepcnt; /* number of keepalives */ extern int tcp_delacktime; /* time before sending a delayed ACK */ extern int tcp_maxpersistidle; +extern int tcp_rexmit_initial; extern int tcp_rexmit_min; extern int tcp_rexmit_slop; extern int tcp_msl; extern int tcp_ttl; /* time to live for TCP segs */ extern int tcp_backoff[]; -extern int tcp_syn_backoff[]; +extern int tcp_totbackoff; +extern int tcp_rexmit_drop_options; extern int tcp_finwait2_timeout; extern int tcp_fast_finwait2_recycle; +VNET_DECLARE(int, tcp_always_keepalive); +#define V_tcp_always_keepalive VNET(tcp_always_keepalive) +VNET_DECLARE(int, tcp_pmtud_blackhole_detect); +#define V_tcp_pmtud_blackhole_detect VNET(tcp_pmtud_blackhole_detect) +VNET_DECLARE(int, tcp_pmtud_blackhole_mss); +#define V_tcp_pmtud_blackhole_mss VNET(tcp_pmtud_blackhole_mss) +VNET_DECLARE(int, tcp_v6pmtud_blackhole_mss); +#define V_tcp_v6pmtud_blackhole_mss VNET(tcp_v6pmtud_blackhole_mss) + +void tcp_inpinfo_lock_del(struct inpcb *inp, struct tcpcb *tp); + void tcp_timer_init(void); void tcp_timer_2msl(void *xtp); void tcp_timer_discard(void *); @@ -200,8 +226,6 @@ void tcp_timer_keep(void *xtp); void tcp_timer_persist(void *xtp); void tcp_timer_rexmt(void *xtp); void tcp_timer_delack(void *xtp); -void tcp_timer_to_xtimer(struct tcpcb *tp, struct tcp_timer *timer, - struct xtcp_timer *xtimer); #endif /* _KERNEL */ diff --git a/tools/compat/include/netinet/tcp_var.h b/tools/compat/include/netinet/tcp_var.h index abfa21ab2..e21920035 100644 --- a/tools/compat/include/netinet/tcp_var.h +++ b/tools/compat/include/netinet/tcp_var.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993, 1994, 1995 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -39,23 +41,55 @@ #ifdef _KERNEL #include #include +#endif -/* - * Kernel variables for tcp. +#define TCP_END_BYTE_INFO 8 /* Bytes that makeup the "end information array" */ +/* Types of ending byte info */ +#define TCP_EI_EMPTY_SLOT 0 +#define TCP_EI_STATUS_CLIENT_FIN 0x1 +#define TCP_EI_STATUS_CLIENT_RST 0x2 +#define TCP_EI_STATUS_SERVER_FIN 0x3 +#define TCP_EI_STATUS_SERVER_RST 0x4 +#define TCP_EI_STATUS_RETRAN 0x5 +#define TCP_EI_STATUS_PROGRESS 0x6 +#define TCP_EI_STATUS_PERSIST_MAX 0x7 +#define TCP_EI_STATUS_KEEP_MAX 0x8 +#define TCP_EI_STATUS_DATA_A_CLOSE 0x9 +#define TCP_EI_STATUS_RST_IN_FRONT 0xa +#define TCP_EI_STATUS_2MSL 0xb +#define TCP_EI_STATUS_MAX_VALUE 0xb + +/************************************************/ +/* Status bits we track to assure no duplicates, + * the bits here are not used by the code but + * for human representation. To check a bit we + * take and shift over by 1 minus the value (1-8). */ -VNET_DECLARE(int, tcp_do_rfc1323); -#define V_tcp_do_rfc1323 VNET(tcp_do_rfc1323) - -#endif /* _KERNEL */ +/************************************************/ +#define TCP_EI_BITS_CLIENT_FIN 0x001 +#define TCP_EI_BITS_CLIENT_RST 0x002 +#define TCP_EI_BITS_SERVER_FIN 0x004 +#define TCP_EI_BITS_SERVER_RST 0x008 +#define TCP_EI_BITS_RETRAN 0x010 +#define TCP_EI_BITS_PROGRESS 0x020 +#define TCP_EI_BITS_PRESIST_MAX 0x040 +#define TCP_EI_BITS_KEEP_MAX 0x080 +#define TCP_EI_BITS_DATA_A_CLO 0x100 +#define TCP_EI_BITS_RST_IN_FR 0x200 /* a front state reset */ +#define TCP_EI_BITS_2MS_TIMER 0x400 /* 2 MSL timer expired */ +#if defined(_KERNEL) || defined(_WANT_TCPCB) /* TCP segment queue entry */ struct tseg_qent { - LIST_ENTRY(tseg_qent) tqe_q; + TAILQ_ENTRY(tseg_qent) tqe_q; + struct mbuf *tqe_m; /* mbuf contains packet */ + struct mbuf *tqe_last; /* last mbuf in chain */ + tcp_seq tqe_start; /* TCP Sequence number start */ int tqe_len; /* TCP segment data length */ - struct tcphdr *tqe_th; /* a pointer to tcp header */ - struct mbuf *tqe_m; /* mbuf contains packet */ + uint32_t tqe_flags; /* The flags from the th->th_flags */ + uint32_t tqe_mbuf_cnt; /* Count of mbuf overhead */ }; -LIST_HEAD(tsegqe_head, tseg_qent); +TAILQ_HEAD(tsegqe_head, tseg_qent); struct sackblk { tcp_seq start; /* start seq no. of sack block */ @@ -71,26 +105,187 @@ struct sackhole { struct sackhint { struct sackhole *nexthole; - int sack_bytes_rexmit; + int32_t sack_bytes_rexmit; tcp_seq last_sack_ack; /* Most recent/largest sacked ack */ - int ispare; /* explicit pad for 64bit alignment */ - int sacked_bytes; /* - * Total sacked bytes reported by the + int32_t delivered_data; /* Newly acked data from last SACK */ + + int32_t sacked_bytes; /* Total sacked bytes reported by the * receiver via sack option */ - uint32_t _pad1[1]; /* TBD */ - uint64_t _pad[1]; /* TBD */ + uint32_t recover_fs; /* Flight Size at the start of Loss recovery */ + uint32_t prr_delivered; /* Total bytes delivered using PRR */ + uint32_t prr_out; /* Bytes sent during IN_RECOVERY */ }; +#define SEGQ_EMPTY(tp) TAILQ_EMPTY(&(tp)->t_segq) + +STAILQ_HEAD(tcp_log_stailq, tcp_log_mem); + +/* + * Tcp control block, one per tcp; fields: + * Organized for 64 byte cacheline efficiency based + * on common tcp_input/tcp_output processing. + */ +struct tcpcb { + /* Cache line 1 */ + struct inpcb *t_inpcb; /* back pointer to internet pcb */ + struct tcp_function_block *t_fb;/* TCP function call block */ + void *t_fb_ptr; /* Pointer to t_fb specific data */ + uint32_t t_maxseg:24, /* maximum segment size */ + t_logstate:8; /* State of "black box" logging */ + uint32_t t_port:16, /* Tunneling (over udp) port */ + t_state:4, /* state of this connection */ + t_idle_reduce : 1, + t_delayed_ack: 7, /* Delayed ack variable */ + t_fin_is_rst: 1, /* Are fin's treated as resets */ + t_log_state_set: 1, + bits_spare : 2; + u_int t_flags; + tcp_seq snd_una; /* sent but unacknowledged */ + tcp_seq snd_max; /* highest sequence number sent; + * used to recognize retransmits + */ + tcp_seq snd_nxt; /* send next */ + tcp_seq snd_up; /* send urgent pointer */ + uint32_t snd_wnd; /* send window */ + uint32_t snd_cwnd; /* congestion-controlled window */ + uint32_t t_peakrate_thr; /* pre-calculated peak rate threshold */ + /* Cache line 2 */ + u_int32_t ts_offset; /* our timestamp offset */ + u_int32_t rfbuf_ts; /* recv buffer autoscaling timestamp */ + int rcv_numsacks; /* # distinct sack blks present */ + u_int t_tsomax; /* TSO total burst length limit in bytes */ + u_int t_tsomaxsegcount; /* TSO maximum segment count */ + u_int t_tsomaxsegsize; /* TSO maximum segment size in bytes */ + tcp_seq rcv_nxt; /* receive next */ + tcp_seq rcv_adv; /* advertised window */ + uint32_t rcv_wnd; /* receive window */ + u_int t_flags2; /* More tcpcb flags storage */ + int t_srtt; /* smoothed round-trip time */ + int t_rttvar; /* variance in round-trip time */ + u_int32_t ts_recent; /* timestamp echo data */ + u_char snd_scale; /* window scaling for send window */ + u_char rcv_scale; /* window scaling for recv window */ + u_char snd_limited; /* segments limited transmitted */ + u_char request_r_scale; /* pending window scaling */ + tcp_seq last_ack_sent; + u_int t_rcvtime; /* inactivity time */ + /* Cache line 3 */ + tcp_seq rcv_up; /* receive urgent pointer */ + int t_segqlen; /* segment reassembly queue length */ + uint32_t t_segqmbuflen; /* Count of bytes mbufs on all entries */ + struct tsegqe_head t_segq; /* segment reassembly queue */ + struct mbuf *t_in_pkt; + struct mbuf *t_tail_pkt; + struct tcp_timer *t_timers; /* All the TCP timers in one struct */ + struct vnet *t_vnet; /* back pointer to parent vnet */ + uint32_t snd_ssthresh; /* snd_cwnd size threshold for + * for slow start exponential to + * linear switch + */ + tcp_seq snd_wl1; /* window update seg seq number */ + /* Cache line 4 */ + tcp_seq snd_wl2; /* window update seg ack number */ + + tcp_seq irs; /* initial receive sequence number */ + tcp_seq iss; /* initial send sequence number */ + u_int t_acktime; /* RACK and BBR incoming new data was acked */ + u_int t_sndtime; /* time last data was sent */ + u_int ts_recent_age; /* when last updated */ + tcp_seq snd_recover; /* for use in NewReno Fast Recovery */ + uint16_t cl4_spare; /* Spare to adjust CL 4 */ + char t_oobflags; /* have some */ + char t_iobc; /* input character */ + int t_rxtcur; /* current retransmit value (ticks) */ + + int t_rxtshift; /* log(2) of rexmt exp. backoff */ + u_int t_rtttime; /* RTT measurement start time */ + + tcp_seq t_rtseq; /* sequence number being timed */ + u_int t_starttime; /* time connection was established */ + u_int t_fbyte_in; /* ticks time when first byte queued in */ + u_int t_fbyte_out; /* ticks time when first byte queued out */ + + u_int t_pmtud_saved_maxseg; /* pre-blackhole MSS */ + int t_blackhole_enter; /* when to enter blackhole detection */ + int t_blackhole_exit; /* when to exit blackhole detection */ + u_int t_rttmin; /* minimum rtt allowed */ + + u_int t_rttbest; /* best rtt we've seen */ + + int t_softerror; /* possible error not yet reported */ + uint32_t max_sndwnd; /* largest window peer has offered */ + /* Cache line 5 */ + uint32_t snd_cwnd_prev; /* cwnd prior to retransmit */ + uint32_t snd_ssthresh_prev; /* ssthresh prior to retransmit */ + tcp_seq snd_recover_prev; /* snd_recover prior to retransmit */ + int t_sndzerowin; /* zero-window updates sent */ + u_long t_rttupdated; /* number of times rtt sampled */ + int snd_numholes; /* number of holes seen by sender */ + u_int t_badrxtwin; /* window for retransmit recovery */ + TAILQ_HEAD(sackhole_head, sackhole) snd_holes; + /* SACK scoreboard (sorted) */ + tcp_seq snd_fack; /* last seq number(+1) sack'd by rcv'r*/ + struct sackblk sackblks[MAX_SACK_BLKS]; /* seq nos. of sack blocks */ + struct sackhint sackhint; /* SACK scoreboard hint */ + int t_rttlow; /* smallest observerved RTT */ + int rfbuf_cnt; /* recv buffer autoscaling byte count */ + struct toedev *tod; /* toedev handling this connection */ + int t_sndrexmitpack; /* retransmit packets sent */ + int t_rcvoopack; /* out-of-order packets received */ + void *t_toe; /* TOE pcb pointer */ + struct cc_algo *cc_algo; /* congestion control algorithm */ + struct cc_var *ccv; /* congestion control specific vars */ + struct osd *osd; /* storage for Khelp module data */ + int t_bytes_acked; /* # bytes acked during current RTT */ + u_int t_maxunacktime; + u_int t_keepinit; /* time to establish connection */ + u_int t_keepidle; /* time before keepalive probes begin */ + u_int t_keepintvl; /* interval between keepalives */ + u_int t_keepcnt; /* number of keepalives before close */ + int t_dupacks; /* consecutive dup acks recd */ + int t_lognum; /* Number of log entries */ + int t_loglimit; /* Maximum number of log entries */ + int64_t t_pacing_rate; /* bytes / sec, -1 => unlimited */ + struct tcp_log_stailq t_logs; /* Log buffer */ + struct tcp_log_id_node *t_lin; + struct tcp_log_id_bucket *t_lib; + const char *t_output_caller; /* Function that called tcp_output */ + struct statsblob *t_stats; /* Per-connection stats */ + uint32_t t_logsn; /* Log "serial number" */ + uint32_t gput_ts; /* Time goodput measurement started */ + tcp_seq gput_seq; /* Outbound measurement seq */ + tcp_seq gput_ack; /* Inbound measurement ack */ + int32_t t_stats_gput_prev; /* XXXLAS: Prev gput measurement */ + uint8_t t_tfo_client_cookie_len; /* TCP Fast Open client cookie length */ + uint32_t t_end_info_status; /* Status flag of end info */ + unsigned int *t_tfo_pending; /* TCP Fast Open server pending counter */ + union { + uint8_t client[TCP_FASTOPEN_MAX_COOKIE_LEN]; + uint64_t server; + } t_tfo_cookie; /* TCP Fast Open cookie to send */ + union { + uint8_t t_end_info_bytes[TCP_END_BYTE_INFO]; + uint64_t t_end_info; + }; +#ifdef TCPPCAP + struct mbufq t_inpkts; /* List of saved input packets. */ + struct mbufq t_outpkts; /* List of saved output packets. */ +#endif +}; +#endif /* _KERNEL || _WANT_TCPCB */ + +#ifdef _KERNEL struct tcptemp { u_char tt_ipgen[40]; /* the size must be of max ip header, now IPv6 */ struct tcphdr tt_t; }; -#define tcp6cb tcpcb /* for KAME src sync over BSD*'s */ +/* Minimum map entries limit value, if set */ +#define TCP_MIN_MAP_ENTRIES_LIMIT 128 -/* +/* * TODO: We yet need to brave plowing in * to tcp_input() and the pru_usrreq() block. * Right now these go to the old standards which @@ -101,10 +296,6 @@ struct tcptemp { */ /* Flags for tcp functions */ #define TCP_FUNC_BEING_REMOVED 0x01 /* Can no longer be referenced */ -struct tcpcb; -struct inpcb; -struct sockopt; -struct socket; /* * If defining the optional tcp_timers, in the @@ -116,19 +307,40 @@ struct socket; * does not know your callbacks you must provide a * stop_all function that loops through and calls * tcp_timer_stop() with each of your defined timers. + * Adding a tfb_tcp_handoff_ok function allows the socket + * option to change stacks to query you even if the + * connection is in a later stage. You return 0 to + * say you can take over and run your stack, you return + * non-zero (an error number) to say no you can't. + * If the function is undefined you can only change + * in the early states (before connect or listen). + * tfb_tcp_fb_fini is changed to add a flag to tell + * the old stack if the tcb is being destroyed or + * not. A one in the flag means the TCB is being + * destroyed, a zero indicates its transitioning to + * another stack (via socket option). */ struct tcp_function_block { char tfb_tcp_block_name[TCP_FUNCTION_NAME_LEN_MAX]; int (*tfb_tcp_output)(struct tcpcb *); + int (*tfb_tcp_output_wtime)(struct tcpcb *, const struct timeval *); void (*tfb_tcp_do_segment)(struct mbuf *, struct tcphdr *, struct socket *, struct tcpcb *, + int, int, uint8_t); + int (*tfb_do_queued_segments)(struct socket *, struct tcpcb *, int); + int (*tfb_do_segment_nounlock)(struct mbuf *, struct tcphdr *, + struct socket *, struct tcpcb *, int, int, uint8_t, - int); + int, struct timeval *); + void (*tfb_tcp_hpts_do_segment)(struct mbuf *, struct tcphdr *, + struct socket *, struct tcpcb *, + int, int, uint8_t, + int, struct timeval *); int (*tfb_tcp_ctloutput)(struct socket *so, struct sockopt *sopt, struct inpcb *inp, struct tcpcb *tp); /* Optional memory allocation/free routine */ - void (*tfb_tcp_fb_init)(struct tcpcb *); - void (*tfb_tcp_fb_fini)(struct tcpcb *); + int (*tfb_tcp_fb_init)(struct tcpcb *); + void (*tfb_tcp_fb_fini)(struct tcpcb *, int); /* Optional timers, must define all if you define one */ int (*tfb_tcp_timer_stop_all)(struct tcpcb *); void (*tfb_tcp_timer_activate)(struct tcpcb *, @@ -136,190 +348,55 @@ struct tcp_function_block { int (*tfb_tcp_timer_active)(struct tcpcb *, uint32_t); void (*tfb_tcp_timer_stop)(struct tcpcb *, uint32_t); void (*tfb_tcp_rexmit_tmr)(struct tcpcb *); + int (*tfb_tcp_handoff_ok)(struct tcpcb *); + void (*tfb_tcp_mtu_chg)(struct tcpcb *); + int (*tfb_pru_options)(struct tcpcb *, int); volatile uint32_t tfb_refcnt; uint32_t tfb_flags; + uint8_t tfb_id; }; struct tcp_function { - TAILQ_ENTRY(tcp_function) tf_next; - struct tcp_function_block *tf_fb; + TAILQ_ENTRY(tcp_function) tf_next; + char tf_name[TCP_FUNCTION_NAME_LEN_MAX]; + struct tcp_function_block *tf_fb; }; TAILQ_HEAD(tcp_funchead, tcp_function); - -/* - * Tcp control block, one per tcp; fields: - * Organized for 16 byte cacheline efficiency. - */ -struct tcpcb { - struct tsegqe_head t_segq; /* segment reassembly queue */ - void *t_pspare[2]; /* new reassembly queue */ - int t_segqlen; /* segment reassembly queue length */ - int t_dupacks; /* consecutive dup acks recd */ - - struct tcp_timer *t_timers; /* All the TCP timers in one struct */ - - struct inpcb *t_inpcb; /* back pointer to internet pcb */ - int t_state; /* state of this connection */ - u_int t_flags; - - struct vnet *t_vnet; /* back pointer to parent vnet */ - - tcp_seq snd_una; /* sent but unacknowledged */ - tcp_seq snd_max; /* highest sequence number sent; - * used to recognize retransmits - */ - tcp_seq snd_nxt; /* send next */ - tcp_seq snd_up; /* send urgent pointer */ - - tcp_seq snd_wl1; /* window update seg seq number */ - tcp_seq snd_wl2; /* window update seg ack number */ - tcp_seq iss; /* initial send sequence number */ - tcp_seq irs; /* initial receive sequence number */ - - tcp_seq rcv_nxt; /* receive next */ - tcp_seq rcv_adv; /* advertised window */ - u_long rcv_wnd; /* receive window */ - tcp_seq rcv_up; /* receive urgent pointer */ - - u_long snd_wnd; /* send window */ - u_long snd_cwnd; /* congestion-controlled window */ - u_long snd_spare1; /* unused */ - u_long snd_ssthresh; /* snd_cwnd size threshold for - * for slow start exponential to - * linear switch - */ - u_long snd_spare2; /* unused */ - tcp_seq snd_recover; /* for use in NewReno Fast Recovery */ - - u_int t_rcvtime; /* inactivity time */ - u_int t_starttime; /* time connection was established */ - u_int t_rtttime; /* RTT measurement start time */ - tcp_seq t_rtseq; /* sequence number being timed */ - - u_int t_bw_spare1; /* unused */ - tcp_seq t_bw_spare2; /* unused */ - - int t_rxtcur; /* current retransmit value (ticks) */ - u_int t_maxseg; /* maximum segment size */ - u_int t_pmtud_saved_maxseg; /* pre-blackhole MSS */ - int t_srtt; /* smoothed round-trip time */ - int t_rttvar; /* variance in round-trip time */ - - int t_rxtshift; /* log(2) of rexmt exp. backoff */ - u_int t_rttmin; /* minimum rtt allowed */ - u_int t_rttbest; /* best rtt we've seen */ - u_long t_rttupdated; /* number of times rtt sampled */ - u_long max_sndwnd; /* largest window peer has offered */ - - int t_softerror; /* possible error not yet reported */ -/* out-of-band data */ - char t_oobflags; /* have some */ - char t_iobc; /* input character */ -/* RFC 1323 variables */ - u_char snd_scale; /* window scaling for send window */ - u_char rcv_scale; /* window scaling for recv window */ - u_char request_r_scale; /* pending window scaling */ - u_int32_t ts_recent; /* timestamp echo data */ - u_int ts_recent_age; /* when last updated */ - u_int32_t ts_offset; /* our timestamp offset */ - - tcp_seq last_ack_sent; -/* experimental */ - u_long snd_cwnd_prev; /* cwnd prior to retransmit */ - u_long snd_ssthresh_prev; /* ssthresh prior to retransmit */ - tcp_seq snd_recover_prev; /* snd_recover prior to retransmit */ - int t_sndzerowin; /* zero-window updates sent */ - u_int t_badrxtwin; /* window for retransmit recovery */ - u_char snd_limited; /* segments limited transmitted */ -/* SACK related state */ - int snd_numholes; /* number of holes seen by sender */ - TAILQ_HEAD(sackhole_head, sackhole) snd_holes; - /* SACK scoreboard (sorted) */ - tcp_seq snd_fack; /* last seq number(+1) sack'd by rcv'r*/ - int rcv_numsacks; /* # distinct sack blks present */ - struct sackblk sackblks[MAX_SACK_BLKS]; /* seq nos. of sack blocks */ - tcp_seq sack_newdata; /* New data xmitted in this recovery - episode starts at this seq number */ - struct sackhint sackhint; /* SACK scoreboard hint */ - int t_rttlow; /* smallest observerved RTT */ - u_int32_t rfbuf_ts; /* recv buffer autoscaling timestamp */ - int rfbuf_cnt; /* recv buffer autoscaling byte count */ - struct toedev *tod; /* toedev handling this connection */ - int t_sndrexmitpack; /* retransmit packets sent */ - int t_rcvoopack; /* out-of-order packets received */ - void *t_toe; /* TOE pcb pointer */ - int t_bytes_acked; /* # bytes acked during current RTT */ - struct cc_algo *cc_algo; /* congestion control algorithm */ - struct cc_var *ccv; /* congestion control specific vars */ - struct osd *osd; /* storage for Khelp module data */ - - u_int t_keepinit; /* time to establish connection */ - u_int t_keepidle; /* time before keepalive probes begin */ - u_int t_keepintvl; /* interval between keepalives */ - u_int t_keepcnt; /* number of keepalives before close */ - - u_int t_tsomax; /* TSO total burst length limit in bytes */ - u_int t_tsomaxsegcount; /* TSO maximum segment count */ - u_int t_tsomaxsegsize; /* TSO maximum segment size in bytes */ - u_int t_flags2; /* More tcpcb flags storage */ -#if defined(_KERNEL) && defined(TCP_RFC7413) - uint32_t t_ispare[6]; /* 5 UTO, 1 TBD */ - uint64_t t_tfo_cookie; /* TCP Fast Open cookie */ -#else - uint32_t t_ispare[8]; /* 5 UTO, 3 TBD */ -#endif - struct tcp_function_block *t_fb;/* TCP function call block */ - void *t_fb_ptr; /* Pointer to t_fb specific data */ -#if defined(_KERNEL) && defined(TCP_RFC7413) - unsigned int *t_tfo_pending; /* TCP Fast Open pending counter */ - void *t_pspare2[1]; /* 1 TCP_SIGNATURE */ -#else - void *t_pspare2[2]; /* 1 TCP_SIGNATURE, 1 TBD */ -#endif -#if defined(_KERNEL) && defined(TCPPCAP) - struct mbufq t_inpkts; /* List of saved input packets. */ - struct mbufq t_outpkts; /* List of saved output packets. */ -#ifdef _LP64 - uint64_t _pad[0]; /* all used! */ -#else - uint64_t _pad[2]; /* 2 are available */ -#endif /* _LP64 */ -#else - uint64_t _pad[6]; -#endif /* defined(_KERNEL) && defined(TCPPCAP) */ -}; +#endif /* _KERNEL */ /* * Flags and utility macros for the t_flags field. */ -#define TF_ACKNOW 0x000001 /* ack peer immediately */ -#define TF_DELACK 0x000002 /* ack, but try to delay it */ -#define TF_NODELAY 0x000004 /* don't delay packets to coalesce */ -#define TF_NOOPT 0x000008 /* don't use tcp options */ -#define TF_SENTFIN 0x000010 /* have sent FIN */ -#define TF_REQ_SCALE 0x000020 /* have/will request window scaling */ -#define TF_RCVD_SCALE 0x000040 /* other side has requested scaling */ -#define TF_REQ_TSTMP 0x000080 /* have/will request timestamps */ -#define TF_RCVD_TSTMP 0x000100 /* a timestamp was received in SYN */ -#define TF_SACK_PERMIT 0x000200 /* other side said I could SACK */ -#define TF_NEEDSYN 0x000400 /* send SYN (implicit state) */ -#define TF_NEEDFIN 0x000800 /* send FIN (implicit state) */ -#define TF_NOPUSH 0x001000 /* don't push */ -#define TF_PREVVALID 0x002000 /* saved values for bad rxmit valid */ -#define TF_MORETOCOME 0x010000 /* More data to be appended to sock */ -#define TF_LQ_OVERFLOW 0x020000 /* listen queue overflow */ -#define TF_LASTIDLE 0x040000 /* connection was previously idle */ -#define TF_RXWIN0SENT 0x080000 /* sent a receiver win 0 in response */ -#define TF_FASTRECOVERY 0x100000 /* in NewReno Fast Recovery */ -#define TF_WASFRECOVERY 0x200000 /* was in NewReno Fast Recovery */ -#define TF_SIGNATURE 0x400000 /* require MD5 digests (RFC2385) */ -#define TF_FORCEDATA 0x800000 /* force out a byte */ -#define TF_TSO 0x1000000 /* TSO enabled on this connection */ -#define TF_TOE 0x2000000 /* this connection is offloaded */ -#define TF_ECN_PERMIT 0x4000000 /* connection ECN-ready */ -#define TF_ECN_SND_CWR 0x8000000 /* ECN CWR in queue */ -#define TF_ECN_SND_ECE 0x10000000 /* ECN ECE in queue */ +#define TF_ACKNOW 0x00000001 /* ack peer immediately */ +#define TF_DELACK 0x00000002 /* ack, but try to delay it */ +#define TF_NODELAY 0x00000004 /* don't delay packets to coalesce */ +#define TF_NOOPT 0x00000008 /* don't use tcp options */ +#define TF_SENTFIN 0x00000010 /* have sent FIN */ +#define TF_REQ_SCALE 0x00000020 /* have/will request window scaling */ +#define TF_RCVD_SCALE 0x00000040 /* other side has requested scaling */ +#define TF_REQ_TSTMP 0x00000080 /* have/will request timestamps */ +#define TF_RCVD_TSTMP 0x00000100 /* a timestamp was received in SYN */ +#define TF_SACK_PERMIT 0x00000200 /* other side said I could SACK */ +#define TF_NEEDSYN 0x00000400 /* send SYN (implicit state) */ +#define TF_NEEDFIN 0x00000800 /* send FIN (implicit state) */ +#define TF_NOPUSH 0x00001000 /* don't push */ +#define TF_PREVVALID 0x00002000 /* saved values for bad rxmit valid */ +#define TF_WAKESOR 0x00004000 /* wake up receive socket */ +#define TF_GPUTINPROG 0x00008000 /* Goodput measurement in progress */ +#define TF_MORETOCOME 0x00010000 /* More data to be appended to sock */ +#define TF_LQ_OVERFLOW 0x00020000 /* listen queue overflow */ +#define TF_LASTIDLE 0x00040000 /* connection was previously idle */ +#define TF_RXWIN0SENT 0x00080000 /* sent a receiver win 0 in response */ +#define TF_FASTRECOVERY 0x00100000 /* in NewReno Fast Recovery */ +#define TF_WASFRECOVERY 0x00200000 /* was in NewReno Fast Recovery */ +#define TF_SIGNATURE 0x00400000 /* require MD5 digests (RFC2385) */ +#define TF_FORCEDATA 0x00800000 /* force out a byte */ +#define TF_TSO 0x01000000 /* TSO enabled on this connection */ +#define TF_TOE 0x02000000 /* this connection is offloaded */ +#define TF_WAKESOW 0x04000000 /* wake up send socket */ +#define TF_UNUSED1 0x08000000 /* unused */ +#define TF_UNUSED2 0x10000000 /* unused */ #define TF_CONGRECOVERY 0x20000000 /* congestion recovery mode */ #define TF_WASCRECOVERY 0x40000000 /* was in congestion recovery */ #define TF_FASTOPEN 0x80000000 /* TCP Fast Open indication */ @@ -336,6 +413,12 @@ struct tcpcb { #define ENTER_RECOVERY(t_flags) t_flags |= (TF_CONGRECOVERY | TF_FASTRECOVERY) #define EXIT_RECOVERY(t_flags) t_flags &= ~(TF_CONGRECOVERY | TF_FASTRECOVERY) +#if defined(_KERNEL) && !defined(TCP_RFC7413) +#define IS_FASTOPEN(t_flags) (false) +#else +#define IS_FASTOPEN(t_flags) (t_flags & TF_FASTOPEN) +#endif + #define BYTES_THIS_ACK(tp, th) (th->th_ack - tp->snd_una) /* @@ -344,28 +427,19 @@ struct tcpcb { #define TCPOOB_HAVEDATA 0x01 #define TCPOOB_HADDATA 0x02 -#ifdef TCP_SIGNATURE /* - * Defines which are needed by the xform_tcp module and tcp_[in|out]put - * for SADB verification and lookup. - */ -#define TCP_SIGLEN 16 /* length of computed digest in bytes */ -#define TCP_KEYLEN_MIN 1 /* minimum length of TCP-MD5 key */ -#define TCP_KEYLEN_MAX 80 /* maximum length of TCP-MD5 key */ -/* - * Only a single SA per host may be specified at this time. An SPI is - * needed in order for the KEY_ALLOCSA() lookup to work. - */ -#define TCP_SIG_SPI 0x1000 -#endif /* TCP_SIGNATURE */ - -/* - * Flags for PLPMTU handling, t_flags2 + * Flags for the extended TCP flags field, t_flags2 */ #define TF2_PLPMTU_BLACKHOLE 0x00000001 /* Possible PLPMTUD Black Hole. */ #define TF2_PLPMTU_PMTUD 0x00000002 /* Allowed to attempt PLPMTUD. */ #define TF2_PLPMTU_MAXSEGSNT 0x00000004 /* Last seg sent was full seg. */ - +#define TF2_LOG_AUTO 0x00000008 /* Session is auto-logging. */ +#define TF2_DROP_AF_DATA 0x00000010 /* Drop after all data ack'd */ +#define TF2_ECN_PERMIT 0x00000020 /* connection ECN-ready */ +#define TF2_ECN_SND_CWR 0x00000040 /* ECN CWR in queue */ +#define TF2_ECN_SND_ECE 0x00000080 /* ECN ECE in queue */ +#define TF2_ACE_PERMIT 0x00000100 /* Accurate ECN mode */ +#define TF2_FBYTES_COMPLETE 0x00000400 /* We have first bytes in and out */ /* * Structure to hold TCP options that are only used during segment * processing (in tcp_input), but not held in the tcpcb. @@ -388,7 +462,7 @@ struct tcpopt { u_int32_t to_tsecr; /* reflected timestamp */ u_char *to_sacks; /* pointer to the first SACK blocks */ u_char *to_signature; /* pointer to the TCP-MD5 signature */ - u_char *to_tfo_cookie; /* pointer to the TFO cookie */ + u_int8_t *to_tfo_cookie; /* pointer to the TFO cookie */ u_int16_t to_mss; /* maximum segment size */ u_int8_t to_wscale; /* window scaling */ u_int8_t to_nsacks; /* number of SACK blocks */ @@ -402,13 +476,13 @@ struct tcpopt { #define TO_SYN 0x01 /* parse SYN-only options */ struct hc_metrics_lite { /* must stay in sync with hc_metrics */ - u_long rmx_mtu; /* MTU for this path */ - u_long rmx_ssthresh; /* outbound gateway buffer limit */ - u_long rmx_rtt; /* estimated round trip time */ - u_long rmx_rttvar; /* estimated rtt variance */ - u_long rmx_cwnd; /* congestion window */ - u_long rmx_sendpipe; /* outbound delay-bandwidth product */ - u_long rmx_recvpipe; /* inbound delay-bandwidth product */ + uint32_t rmx_mtu; /* MTU for this path */ + uint32_t rmx_ssthresh; /* outbound gateway buffer limit */ + uint32_t rmx_rtt; /* estimated round trip time */ + uint32_t rmx_rttvar; /* estimated rtt variance */ + uint32_t rmx_cwnd; /* congestion window */ + uint32_t rmx_sendpipe; /* outbound delay-bandwidth product */ + uint32_t rmx_recvpipe; /* inbound delay-bandwidth product */ }; /* @@ -433,7 +507,7 @@ struct tcptw { tcp_seq iss; tcp_seq irs; u_short last_win; /* cached window value */ - u_short tw_so_options; /* copy of so_options */ + short tw_so_options; /* copy of so_options */ struct ucred *tw_cred; /* user credentials */ u_int32_t t_recent; u_int32_t ts_offset; /* our timestamp offset */ @@ -584,7 +658,7 @@ struct tcpstat { uint64_t tcps_sack_rcv_blocks; /* SACK blocks (options) received */ uint64_t tcps_sack_send_blocks; /* SACK blocks (options) sent */ uint64_t tcps_sack_sboverflow; /* times scoreboard overflowed */ - + /* ECN related stats */ uint64_t tcps_ecn_ce; /* ECN Congestion Experienced */ uint64_t tcps_ecn_ect0; /* ECN Capable Transport */ @@ -595,10 +669,15 @@ struct tcpstat { /* TCP_SIGNATURE related stats */ uint64_t tcps_sig_rcvgoodsig; /* Total matching signature received */ uint64_t tcps_sig_rcvbadsig; /* Total bad signature received */ - uint64_t tcps_sig_err_buildsig; /* Mismatching signature received */ + uint64_t tcps_sig_err_buildsig; /* Failed to make signature */ uint64_t tcps_sig_err_sigopt; /* No signature expected by socket */ uint64_t tcps_sig_err_nosigopt; /* No signature provided by segment */ + /* Path MTU Discovery Black Hole Detection related stats */ + uint64_t tcps_pmtud_blackhole_activated; /* Black Hole Count */ + uint64_t tcps_pmtud_blackhole_activated_min_mss; /* BH at min MSS Count */ + uint64_t tcps_pmtud_blackhole_failed; /* Black Hole Failure Count */ + uint64_t _pad[12]; /* 6 UTO, 6 TBD */ }; @@ -621,9 +700,10 @@ VNET_PCPUSTAT_DECLARE(struct tcpstat, tcpstat); /* tcp statistics */ /* * Kernel module consumers must use this accessor macro. */ -void kmod_tcpstat_inc(int statnum); -#define KMOD_TCPSTAT_INC(name) \ - kmod_tcpstat_inc(offsetof(struct tcpstat, name) / sizeof(uint64_t)) +void kmod_tcpstat_add(int statnum, int val); +#define KMOD_TCPSTAT_ADD(name, val) \ + kmod_tcpstat_add(offsetof(struct tcpstat, name) / sizeof(uint64_t), val) +#define KMOD_TCPSTAT_INC(name) KMOD_TCPSTAT_ADD(name, 1) /* * Running TCP connection count by state. @@ -644,35 +724,76 @@ struct tcp_hhook_data { struct tcpcb *tp; struct tcphdr *th; struct tcpopt *to; - long len; + uint32_t len; int tso; tcp_seq curack; }; +#ifdef TCP_HHOOK +void hhook_run_tcp_est_out(struct tcpcb *tp, + struct tcphdr *th, struct tcpopt *to, + uint32_t len, int tso); +#endif #endif /* * TCB structure exported to user-land via sysctl(3). + * + * Fields prefixed with "xt_" are unique to the export structure, and fields + * with "t_" or other prefixes match corresponding fields of 'struct tcpcb'. + * + * Legend: + * (s) - used by userland utilities in src + * (p) - used by utilities in ports + * (3) - is known to be used by third party software not in ports + * (n) - no known usage + * * Evil hack: declare only if in_pcb.h and sys/socketvar.h have been * included. Not all of our clients do. */ #if defined(_NETINET_IN_PCB_H_) && defined(_SYS_SOCKETVAR_H_) -struct xtcp_timer { - int tt_rexmt; /* retransmit timer */ - int tt_persist; /* retransmit persistence */ - int tt_keep; /* keepalive */ - int tt_2msl; /* 2*msl TIME_WAIT timer */ - int tt_delack; /* delayed ACK timer */ - int t_rcvtime; /* Time since last packet received */ -}; -struct xtcpcb { - size_t xt_len; - struct inpcb xt_inp; - struct tcpcb xt_tp; - struct xsocket xt_socket; - struct xtcp_timer xt_timer; - u_quad_t xt_alignment_hack; -}; +struct xtcpcb { + ksize_t xt_len; /* length of this structure */ + struct xinpcb xt_inp; + char xt_stack[TCP_FUNCTION_NAME_LEN_MAX]; /* (s) */ + char xt_logid[TCP_LOG_ID_LEN]; /* (s) */ + char xt_cc[TCP_CA_NAME_MAX]; /* (s) */ + int64_t spare64[6]; + int32_t t_state; /* (s,p) */ + uint32_t t_flags; /* (s,p) */ + int32_t t_sndzerowin; /* (s) */ + int32_t t_sndrexmitpack; /* (s) */ + int32_t t_rcvoopack; /* (s) */ + int32_t t_rcvtime; /* (s) */ + int32_t tt_rexmt; /* (s) */ + int32_t tt_persist; /* (s) */ + int32_t tt_keep; /* (s) */ + int32_t tt_2msl; /* (s) */ + int32_t tt_delack; /* (s) */ + int32_t t_logstate; /* (3) */ + uint32_t t_snd_cwnd; /* (s) */ + uint32_t t_snd_ssthresh; /* (s) */ + uint32_t t_maxseg; /* (s) */ + uint32_t t_rcv_wnd; /* (s) */ + uint32_t t_snd_wnd; /* (s) */ + uint32_t xt_ecn; /* (s) */ + int32_t spare32[26]; +}__attribute__((__aligned__(8))); + +#ifdef _KERNEL +void tcp_inptoxtp(const struct inpcb *, struct xtcpcb *); #endif +#endif + +/* + * TCP function information (name-to-id mapping, aliases, and refcnt) + * exported to user-land via sysctl(3). + */ +struct tcp_function_info { + uint32_t tfi_refcnt; + uint8_t tfi_id; + char tfi_name[TCP_FUNCTION_NAME_LEN_MAX]; + char tfi_alias[TCP_FUNCTION_NAME_LEN_MAX]; +}; /* * Identifiers for TCP sysctl nodes @@ -700,47 +821,102 @@ SYSCTL_DECL(_net_inet_tcp_sack); MALLOC_DECLARE(M_TCPLOG); #endif -VNET_DECLARE(struct inpcbhead, tcb); /* queue of active tcpcb's */ -VNET_DECLARE(struct inpcbinfo, tcbinfo); -extern int tcp_log_in_vain; -VNET_DECLARE(int, tcp_mssdflt); /* XXX */ -VNET_DECLARE(int, tcp_minmss); -VNET_DECLARE(int, tcp_delack_enabled); -VNET_DECLARE(int, tcp_do_rfc3390); -VNET_DECLARE(int, tcp_initcwnd_segments); -VNET_DECLARE(int, tcp_sendspace); -VNET_DECLARE(int, tcp_recvspace); +VNET_DECLARE(int, tcp_log_in_vain); +#define V_tcp_log_in_vain VNET(tcp_log_in_vain) + +/* + * Global TCP tunables shared between different stacks. + * Please keep the list sorted. + */ +VNET_DECLARE(int, drop_synfin); VNET_DECLARE(int, path_mtu_discovery); -VNET_DECLARE(int, tcp_do_rfc3465); VNET_DECLARE(int, tcp_abc_l_var); -#define V_tcb VNET(tcb) -#define V_tcbinfo VNET(tcbinfo) -#define V_tcp_mssdflt VNET(tcp_mssdflt) -#define V_tcp_minmss VNET(tcp_minmss) -#define V_tcp_delack_enabled VNET(tcp_delack_enabled) -#define V_tcp_do_rfc3390 VNET(tcp_do_rfc3390) -#define V_tcp_initcwnd_segments VNET(tcp_initcwnd_segments) -#define V_tcp_sendspace VNET(tcp_sendspace) -#define V_tcp_recvspace VNET(tcp_recvspace) -#define V_path_mtu_discovery VNET(path_mtu_discovery) -#define V_tcp_do_rfc3465 VNET(tcp_do_rfc3465) -#define V_tcp_abc_l_var VNET(tcp_abc_l_var) - -VNET_DECLARE(int, tcp_do_sack); /* SACK enabled/disabled */ -VNET_DECLARE(int, tcp_sc_rst_sock_fail); /* RST on sock alloc failure */ -#define V_tcp_do_sack VNET(tcp_do_sack) -#define V_tcp_sc_rst_sock_fail VNET(tcp_sc_rst_sock_fail) - -VNET_DECLARE(int, tcp_do_ecn); /* TCP ECN enabled/disabled */ +VNET_DECLARE(int, tcp_autorcvbuf_max); +VNET_DECLARE(int, tcp_autosndbuf_inc); +VNET_DECLARE(int, tcp_autosndbuf_max); +VNET_DECLARE(int, tcp_delack_enabled); +VNET_DECLARE(int, tcp_do_autorcvbuf); +VNET_DECLARE(int, tcp_do_autosndbuf); +VNET_DECLARE(int, tcp_do_ecn); +VNET_DECLARE(int, tcp_do_newcwv); +VNET_DECLARE(int, tcp_do_rfc1323); +VNET_DECLARE(int, tcp_tolerate_missing_ts); +VNET_DECLARE(int, tcp_do_rfc3042); +VNET_DECLARE(int, tcp_do_rfc3390); +VNET_DECLARE(int, tcp_do_rfc3465); +VNET_DECLARE(int, tcp_do_rfc6675_pipe); +VNET_DECLARE(int, tcp_do_sack); +VNET_DECLARE(int, tcp_do_tso); VNET_DECLARE(int, tcp_ecn_maxretries); -#define V_tcp_do_ecn VNET(tcp_do_ecn) -#define V_tcp_ecn_maxretries VNET(tcp_ecn_maxretries) +VNET_DECLARE(int, tcp_initcwnd_segments); +VNET_DECLARE(int, tcp_insecure_rst); +VNET_DECLARE(int, tcp_insecure_syn); +VNET_DECLARE(uint32_t, tcp_map_entries_limit); +VNET_DECLARE(uint32_t, tcp_map_split_limit); +VNET_DECLARE(int, tcp_minmss); +VNET_DECLARE(int, tcp_mssdflt); +#ifdef STATS +VNET_DECLARE(int, tcp_perconn_stats_dflt_tpl); +VNET_DECLARE(int, tcp_perconn_stats_enable); +#endif /* STATS */ +VNET_DECLARE(int, tcp_recvspace); +VNET_DECLARE(int, tcp_sack_globalholes); +VNET_DECLARE(int, tcp_sack_globalmaxholes); +VNET_DECLARE(int, tcp_sack_maxholes); +VNET_DECLARE(int, tcp_sc_rst_sock_fail); +VNET_DECLARE(int, tcp_sendspace); +VNET_DECLARE(struct inpcbhead, tcb); +VNET_DECLARE(struct inpcbinfo, tcbinfo); +#define V_tcp_do_prr VNET(tcp_do_prr) +#define V_tcp_do_prr_conservative VNET(tcp_do_prr_conservative) +#define V_tcp_do_newcwv VNET(tcp_do_newcwv) +#define V_drop_synfin VNET(drop_synfin) +#define V_path_mtu_discovery VNET(path_mtu_discovery) +#define V_tcb VNET(tcb) +#define V_tcbinfo VNET(tcbinfo) +#define V_tcp_abc_l_var VNET(tcp_abc_l_var) +#define V_tcp_autorcvbuf_max VNET(tcp_autorcvbuf_max) +#define V_tcp_autosndbuf_inc VNET(tcp_autosndbuf_inc) +#define V_tcp_autosndbuf_max VNET(tcp_autosndbuf_max) +#define V_tcp_delack_enabled VNET(tcp_delack_enabled) +#define V_tcp_do_autorcvbuf VNET(tcp_do_autorcvbuf) +#define V_tcp_do_autosndbuf VNET(tcp_do_autosndbuf) +#define V_tcp_do_ecn VNET(tcp_do_ecn) +#define V_tcp_do_rfc1323 VNET(tcp_do_rfc1323) +#define V_tcp_tolerate_missing_ts VNET(tcp_tolerate_missing_ts) +#define V_tcp_ts_offset_per_conn VNET(tcp_ts_offset_per_conn) +#define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042) +#define V_tcp_do_rfc3390 VNET(tcp_do_rfc3390) +#define V_tcp_do_rfc3465 VNET(tcp_do_rfc3465) +#define V_tcp_do_rfc6675_pipe VNET(tcp_do_rfc6675_pipe) +#define V_tcp_do_sack VNET(tcp_do_sack) +#define V_tcp_do_tso VNET(tcp_do_tso) +#define V_tcp_ecn_maxretries VNET(tcp_ecn_maxretries) +#define V_tcp_initcwnd_segments VNET(tcp_initcwnd_segments) +#define V_tcp_insecure_rst VNET(tcp_insecure_rst) +#define V_tcp_insecure_syn VNET(tcp_insecure_syn) +#define V_tcp_map_entries_limit VNET(tcp_map_entries_limit) +#define V_tcp_map_split_limit VNET(tcp_map_split_limit) +#define V_tcp_minmss VNET(tcp_minmss) +#define V_tcp_mssdflt VNET(tcp_mssdflt) +#ifdef STATS +#define V_tcp_perconn_stats_dflt_tpl VNET(tcp_perconn_stats_dflt_tpl) +#define V_tcp_perconn_stats_enable VNET(tcp_perconn_stats_enable) +#endif /* STATS */ +#define V_tcp_recvspace VNET(tcp_recvspace) +#define V_tcp_sack_globalholes VNET(tcp_sack_globalholes) +#define V_tcp_sack_globalmaxholes VNET(tcp_sack_globalmaxholes) +#define V_tcp_sack_maxholes VNET(tcp_sack_maxholes) +#define V_tcp_sc_rst_sock_fail VNET(tcp_sc_rst_sock_fail) +#define V_tcp_sendspace VNET(tcp_sendspace) +#define V_tcp_udp_tunneling_overhead VNET(tcp_udp_tunneling_overhead) +#define V_tcp_udp_tunneling_port VNET(tcp_udp_tunneling_port) + +#ifdef TCP_HHOOK VNET_DECLARE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST + 1]); #define V_tcp_hhh VNET(tcp_hhh) - -VNET_DECLARE(int, tcp_do_rfc6675_pipe); -#define V_tcp_do_rfc6675_pipe VNET(tcp_do_rfc6675_pipe) +#endif int tcp_addoptions(struct tcpopt *, u_char *); int tcp_ccalgounload(struct cc_algo *unload_algo); @@ -760,7 +936,8 @@ char *tcp_log_addrs(struct in_conninfo *, struct tcphdr *, void *, const void *); char *tcp_log_vain(struct in_conninfo *, struct tcphdr *, void *, const void *); -int tcp_reass(struct tcpcb *, struct tcphdr *, int *, struct mbuf *); +int tcp_reass(struct tcpcb *, struct tcphdr *, tcp_seq *, int *, + struct mbuf *); void tcp_reass_global_init(void); void tcp_reass_flush(struct tcpcb *); void tcp_dooptions(struct tcpopt *, u_char *, int, int); @@ -771,26 +948,58 @@ void tcp_pulloutofband(struct socket *, void tcp_xmit_timer(struct tcpcb *, int); void tcp_newreno_partial_ack(struct tcpcb *, struct tcphdr *); void cc_ack_received(struct tcpcb *tp, struct tcphdr *th, - uint16_t type); + uint16_t nsegs, uint16_t type); void cc_conn_init(struct tcpcb *tp); void cc_post_recovery(struct tcpcb *tp, struct tcphdr *th); +void cc_ecnpkt_handler(struct tcpcb *tp, struct tcphdr *th, uint8_t iptos); void cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type); +#ifdef TCP_HHOOK void hhook_run_tcp_est_in(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to); +#endif int tcp_input(struct mbuf **, int *, int); +int tcp_autorcvbuf(struct mbuf *, struct tcphdr *, struct socket *, + struct tcpcb *, int); +void tcp_handle_wakeup(struct tcpcb *, struct socket *); void tcp_do_segment(struct mbuf *, struct tcphdr *, - struct socket *, struct tcpcb *, int, int, uint8_t, - int); + struct socket *, struct tcpcb *, int, int, uint8_t); int register_tcp_functions(struct tcp_function_block *blk, int wait); -int deregister_tcp_functions(struct tcp_function_block *blk); +int register_tcp_functions_as_names(struct tcp_function_block *blk, + int wait, const char *names[], int *num_names); +int register_tcp_functions_as_name(struct tcp_function_block *blk, + const char *name, int wait); +int deregister_tcp_functions(struct tcp_function_block *blk, bool quiesce, + bool force); struct tcp_function_block *find_and_ref_tcp_functions(struct tcp_function_set *fs); -struct tcp_function_block *find_and_ref_tcp_fb(struct tcp_function_block *blk); +void tcp_switch_back_to_default(struct tcpcb *tp); +struct tcp_function_block * +find_and_ref_tcp_fb(struct tcp_function_block *fs); int tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp, struct tcpcb *tp); -u_long tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *); -u_long tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *); +extern counter_u64_t tcp_inp_lro_direct_queue; +extern counter_u64_t tcp_inp_lro_wokeup_queue; +extern counter_u64_t tcp_inp_lro_compressed; +extern counter_u64_t tcp_inp_lro_single_push; +extern counter_u64_t tcp_inp_lro_locks_taken; +extern counter_u64_t tcp_inp_lro_sack_wake; + +#ifdef NETFLIX_EXP_DETECTION +/* Various SACK attack thresholds */ +extern int32_t tcp_force_detection; +extern int32_t tcp_sack_to_ack_thresh; +extern int32_t tcp_sack_to_move_thresh; +extern int32_t tcp_restoral_thresh; +extern int32_t tcp_sad_decay_val; +extern int32_t tcp_sad_pacing_interval; +extern int32_t tcp_sad_low_pps; +extern int32_t tcp_map_minimum; +extern int32_t tcp_attack_on_turns_on_logging; +#endif + +uint32_t tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *); +uint32_t tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *); u_int tcp_maxseg(const struct tcpcb *); void tcp_mss_update(struct tcpcb *, int, int, struct hc_metrics_lite *, struct tcp_ifcap *); @@ -812,25 +1021,17 @@ void tcp_tw_zone_change(void); int tcp_twcheck(struct inpcb *, struct tcpopt *, struct tcphdr *, struct mbuf *, int); void tcp_setpersist(struct tcpcb *); -#ifdef TCP_SIGNATURE -struct secasvar; -struct secasvar *tcp_get_sav(struct mbuf *, u_int); -int tcp_signature_do_compute(struct mbuf *, int, int, u_char *, - struct secasvar *); -int tcp_signature_compute(struct mbuf *, int, int, int, u_char *, u_int); -int tcp_signature_verify(struct mbuf *, int, int, int, struct tcpopt *, - struct tcphdr *, u_int); -int tcp_signature_check(struct mbuf *m, int off0, int tlen, int optlen, - struct tcpopt *to, struct tcphdr *th, u_int tcpbflag); -#endif void tcp_slowtimo(void); struct tcptemp * tcpip_maketemplate(struct inpcb *); void tcpip_fillheaders(struct inpcb *, void *, void *); void tcp_timer_activate(struct tcpcb *, uint32_t, u_int); +int tcp_timer_suspend(struct tcpcb *, uint32_t); +void tcp_timers_unsuspend(struct tcpcb *, uint32_t); int tcp_timer_active(struct tcpcb *, uint32_t); void tcp_timer_stop(struct tcpcb *, uint32_t); void tcp_trace(short, short, struct tcpcb *, void *, struct tcphdr *, int); +int inp_to_cpuid(struct inpcb *inp); /* * All tcp_hc_* functions are IPv4 and IPv6 (via in_conninfo) */ @@ -839,23 +1040,37 @@ void tcp_hc_init(void); void tcp_hc_destroy(void); #endif void tcp_hc_get(struct in_conninfo *, struct hc_metrics_lite *); -u_long tcp_hc_getmtu(struct in_conninfo *); -void tcp_hc_updatemtu(struct in_conninfo *, u_long); +uint32_t tcp_hc_getmtu(struct in_conninfo *); +void tcp_hc_updatemtu(struct in_conninfo *, uint32_t); void tcp_hc_update(struct in_conninfo *, struct hc_metrics_lite *); extern struct pr_usrreqs tcp_usrreqs; -tcp_seq tcp_new_isn(struct tcpcb *); + +uint32_t tcp_new_ts_offset(struct in_conninfo *); +tcp_seq tcp_new_isn(struct in_conninfo *); int tcp_sack_doack(struct tcpcb *, struct tcpopt *, tcp_seq); +void tcp_update_dsack_list(struct tcpcb *, tcp_seq, tcp_seq); void tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_laststart, tcp_seq rcv_lastend); +void tcp_clean_dsack_blocks(struct tcpcb *tp); void tcp_clean_sackreport(struct tcpcb *tp); void tcp_sack_adjust(struct tcpcb *tp); struct sackhole *tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt); +void tcp_prr_partialack(struct tcpcb *, struct tcphdr *); void tcp_sack_partialack(struct tcpcb *, struct tcphdr *); void tcp_free_sackholes(struct tcpcb *tp); int tcp_newreno(struct tcpcb *, struct tcphdr *); -u_long tcp_seq_subtract(u_long, u_long ); int tcp_compute_pipe(struct tcpcb *); +uint32_t tcp_compute_initwnd(uint32_t); +void tcp_sndbuf_autoscale(struct tcpcb *, struct socket *, uint32_t); +int tcp_stats_sample_rollthedice(struct tcpcb *tp, void *seed_bytes, + size_t seed_len); +struct mbuf * + tcp_m_copym(struct mbuf *m, int32_t off0, int32_t *plen, + int32_t seglimit, int32_t segsize, struct sockbuf *sb, bool hw_tls); + +int tcp_stats_init(void); +void tcp_log_end_status(struct tcpcb *tp, uint8_t status); static inline void tcp_fields_to_host(struct tcphdr *th) @@ -867,7 +1082,6 @@ tcp_fields_to_host(struct tcphdr *th) th->th_urp = ntohs(th->th_urp); } -#ifdef TCP_SIGNATURE static inline void tcp_fields_to_net(struct tcphdr *th) { @@ -877,7 +1091,6 @@ tcp_fields_to_net(struct tcphdr *th) th->th_win = htons(th->th_win); th->th_urp = htons(th->th_urp); } -#endif #endif /* _KERNEL */ #endif /* _NETINET_TCP_VAR_H_ */ diff --git a/tools/compat/include/netinet/tcpip.h b/tools/compat/include/netinet/tcpip.h index 3a89d5d5b..f3ed5be95 100644 --- a/tools/compat/include/netinet/tcpip.h +++ b/tools/compat/include/netinet/tcpip.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/tools/compat/include/netinet/udp.h b/tools/compat/include/netinet/udp.h index c2d638dde..263a64fbe 100644 --- a/tools/compat/include/netinet/udp.h +++ b/tools/compat/include/netinet/udp.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. * All rights reserved. @@ -11,7 +13,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -45,7 +47,7 @@ struct udphdr { u_short uh_sum; /* udp checksum */ }; -/* +/* * User-settable options (used with setsockopt). */ #define UDP_ENCAP 1 @@ -58,7 +60,7 @@ struct udphdr { */ /* Encapsulation types. */ #define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */ -#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-02+ */ +#define UDP_ENCAP_ESPINUDP 2 /* RFC3948 */ /* Default ESP in UDP encapsulation port. */ #define UDP_ENCAP_ESPINUDP_PORT 500 diff --git a/tools/compat/include/netinet/udp_var.h b/tools/compat/include/netinet/udp_var.h index 9564da291..37bc0c846 100644 --- a/tools/compat/include/netinet/udp_var.h +++ b/tools/compat/include/netinet/udp_var.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. * All rights reserved. @@ -11,7 +13,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -58,7 +60,7 @@ struct mbuf; typedef void(*udp_tun_func_t)(struct mbuf *, int, struct inpcb *, const struct sockaddr *, void *); typedef void(*udp_tun_icmp_t)(int, struct sockaddr *, void *, void *); - + /* * UDP control block; one per udp. */ @@ -147,9 +149,13 @@ extern u_long udp_sendspace; extern u_long udp_recvspace; VNET_DECLARE(int, udp_cksum); VNET_DECLARE(int, udp_blackhole); +VNET_DECLARE(int, udp_log_in_vain); #define V_udp_cksum VNET(udp_cksum) #define V_udp_blackhole VNET(udp_blackhole) -extern int udp_log_in_vain; +#define V_udp_log_in_vain VNET(udp_log_in_vain) + +VNET_DECLARE(int, zero_checksum_port); +#define V_zero_checksum_port VNET(zero_checksum_port) static __inline struct inpcbinfo * udp_get_inpcbinfo(int protocol) diff --git a/tools/compat/include/netinet6/in6.h b/tools/compat/include/netinet6/in6.h index c84881e40..10bc1f91c 100644 --- a/tools/compat/include/netinet6/in6.h +++ b/tools/compat/include/netinet6/in6.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * @@ -41,7 +43,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -101,7 +103,7 @@ struct in6_addr { }; #define s6_addr __u6_addr.__u6_addr8 -#ifdef _KERNEL /* XXX nonstandard */ +#if defined(_KERNEL) || defined(_STANDALONE) /* XXX nonstandard */ #define s6_addr8 __u6_addr.__u6_addr8 #define s6_addr16 __u6_addr.__u6_addr16 #define s6_addr32 __u6_addr.__u6_addr32 @@ -373,8 +375,9 @@ extern const struct in6_addr in6addr_linklocal_allv2routers; * IP6 route structure */ #if __BSD_VISIBLE +struct nhop_object; struct route_in6 { - struct rtentry *ro_rt; + struct nhop_object *ro_nh; struct llentry *ro_lle; /* * ro_prepend and ro_plen are only used for bpf to pass in a @@ -432,10 +435,7 @@ struct route_in6 { #define IPV6_BINDV6ONLY IPV6_V6ONLY #endif -#if 1 /* IPSEC */ #define IPV6_IPSEC_POLICY 28 /* struct; get/set security policy */ -#endif /* IPSEC */ - /* 29; unused; was IPV6_FAITH */ #if 1 /* IPV6FIREWALL */ #define IPV6_FW_ADD 30 /* add a firewall rule to chain */ @@ -500,6 +500,9 @@ struct route_in6 { #define IPV6_RECVFLOWID 70 /* bool; receive IP6 flowid/flowtype w/ datagram */ #define IPV6_RECVRSSBUCKETID 71 /* bool; receive IP6 RSS bucket id w/ datagram */ +#define IPV6_ORIGDSTADDR 72 /* bool: allow getting dstaddr /port info */ +#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR + /* * The following option is private; do not use it from user applications. * It is deliberately defined to the same value as IP_MSFILTER. @@ -508,6 +511,10 @@ struct route_in6 { * set/get multicast source filter list. */ +/* The following option deals with the 802.1Q Ethernet Priority Code Point */ +#define IPV6_VLAN_PCP 75 /* int; set/get PCP used for packet, */ + /* -1 use interface default */ + /* to define items, should talk with KAME guys first, for *BSD compatibility */ #define IPV6_RTHDR_LOOSE 0 /* this hop need not be a neighbor. XXX old spec */ @@ -521,11 +528,8 @@ struct route_in6 { #define IPV6_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */ /* - * The im6o_membership vector for each socket is now dynamically allocated at - * run-time, bounded by USHRT_MAX, and is reallocated when needed, sized - * according to a power-of-two increment. + * Limit for IPv6 multicast memberships */ -#define IPV6_MIN_MEMBERSHIPS 31 #define IPV6_MAX_MEMBERSHIPS 4095 /* @@ -637,7 +641,12 @@ struct ip6_mtuinfo { * receiving IF. */ #define IPV6CTL_RFC6204W3 50 /* Accept defroute even when forwarding enabled */ -#define IPV6CTL_MAXID 51 +#define IPV6CTL_INTRQMAXLEN 51 /* max length of IPv6 netisr queue */ +#define IPV6CTL_INTRDQMAXLEN 52 /* max length of direct IPv6 netisr + * queue */ +#define IPV6CTL_MAXFRAGSPERPACKET 53 /* Max fragments per packet */ +#define IPV6CTL_MAXFRAGBUCKETSIZE 54 /* Max reassembly queues per bucket */ +#define IPV6CTL_MAXID 55 #endif /* __BSD_VISIBLE */ /* @@ -653,6 +662,7 @@ struct ip6_mtuinfo { #define M_LOOP M_PROTO6 #define M_AUTHIPDGM M_PROTO7 #define M_RTALERT_MLD M_PROTO8 +#define M_FRAGMENTED M_PROTO9 /* contained fragment header */ #ifdef _KERNEL struct cmsghdr; diff --git a/tools/compat/include/netinet6/in6_pcb.h b/tools/compat/include/netinet6/in6_pcb.h index e758dacea..06df113c2 100644 --- a/tools/compat/include/netinet6/in6_pcb.h +++ b/tools/compat/include/netinet6/in6_pcb.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * @@ -41,7 +43,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -84,12 +86,16 @@ void in6_losing(struct inpcb *); int in6_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *); int in6_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *); int in6_pcbconnect_mbuf(struct inpcb *, struct sockaddr *, - struct ucred *, struct mbuf *); + struct ucred *, struct mbuf *, bool); void in6_pcbdisconnect(struct inpcb *); struct inpcb * in6_pcblookup_local(struct inpcbinfo *, struct in6_addr *, u_short, int, struct ucred *); +struct inpcb * + in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, + struct in6_addr *faddr, u_int fport_arg, struct in6_addr *laddr, + u_int lport_arg, int lookupflags, struct ifnet *ifp, uint8_t); struct inpcb * in6_pcblookup(struct inpcbinfo *, struct in6_addr *, u_int, struct in6_addr *, u_int, int, @@ -111,9 +117,9 @@ int in6_getpeeraddr(struct socket *so, struct sockaddr **nam); int in6_getsockaddr(struct socket *so, struct sockaddr **nam); int in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam); int in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam); -int in6_selecthlim(struct in6pcb *, struct ifnet *); +int in6_selecthlim(struct inpcb *, struct ifnet *); int in6_pcbsetport(struct in6_addr *, struct inpcb *, struct ucred *); -void init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m); +void init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m, int); #endif /* _KERNEL */ #endif /* !_NETINET6_IN6_PCB_H_ */ diff --git a/tools/compat/include/netinet6/in6_var.h b/tools/compat/include/netinet6/in6_var.h index 77e5920b0..5f4364c6f 100644 --- a/tools/compat/include/netinet6/in6_var.h +++ b/tools/compat/include/netinet6/in6_var.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * @@ -41,7 +43,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -98,6 +100,7 @@ struct nd_ifinfo; struct scope6_id; struct lltable; struct mld_ifsoftc; +struct in6_multi; struct in6_ifextra { counter_u64_t *in6_ifstat; @@ -111,6 +114,10 @@ struct in6_ifextra { #define LLTABLE6(ifp) (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->lltable) #ifdef _KERNEL + +SLIST_HEAD(in6_multi_head, in6_multi); +MALLOC_DECLARE(M_IP6MADDR); + struct in6_ifaddr { struct ifaddr ia_ifa; /* protocol-independent info */ #define ia_ifp ia_ifa.ifa_ifp @@ -120,7 +127,7 @@ struct in6_ifaddr { struct sockaddr_in6 ia_dstaddr; /* space for destination addr */ struct sockaddr_in6 ia_prefixmask; /* prefix mask */ u_int32_t ia_plen; /* prefix length */ - TAILQ_ENTRY(in6_ifaddr) ia_link; /* list of IPv6 addresses */ + CK_STAILQ_ENTRY(in6_ifaddr) ia_link; /* list of IPv6 addresses */ int ia6_flags; struct in6_addrlifetime ia6_lifetime; @@ -135,12 +142,12 @@ struct in6_ifaddr { /* multicast addresses joined from the kernel */ LIST_HEAD(, in6_multi_mship) ia6_memberships; /* entry in bucket of inet6 addresses */ - LIST_ENTRY(in6_ifaddr) ia6_hash; + CK_LIST_ENTRY(in6_ifaddr) ia6_hash; }; /* List of in6_ifaddr's. */ -TAILQ_HEAD(in6_ifaddrhead, in6_ifaddr); -LIST_HEAD(in6_ifaddrlisthead, in6_ifaddr); +CK_STAILQ_HEAD(in6_ifaddrhead, in6_ifaddr); +CK_LIST_HEAD(in6_ifaddrlisthead, in6_ifaddr); #endif /* _KERNEL */ /* control structure to manage address selection policy */ @@ -595,8 +602,60 @@ struct in6_mfilter { struct ip6_msource_tree im6f_sources; /* source list for (S,G) */ u_long im6f_nsrc; /* # of source entries */ uint8_t im6f_st[2]; /* state before/at commit */ + struct in6_multi *im6f_in6m; /* associated multicast address */ + STAILQ_ENTRY(in6_mfilter) im6f_entry; /* list entry */ }; +/* + * Helper types and functions for IPv4 multicast filters. + */ +STAILQ_HEAD(ip6_mfilter_head, in6_mfilter); + +struct in6_mfilter *ip6_mfilter_alloc(int mflags, int st0, int st1); +void ip6_mfilter_free(struct in6_mfilter *); + +static inline void +ip6_mfilter_init(struct ip6_mfilter_head *head) +{ + + STAILQ_INIT(head); +} + +static inline struct in6_mfilter * +ip6_mfilter_first(const struct ip6_mfilter_head *head) +{ + + return (STAILQ_FIRST(head)); +} + +static inline void +ip6_mfilter_insert(struct ip6_mfilter_head *head, struct in6_mfilter *imf) +{ + + STAILQ_INSERT_TAIL(head, imf, im6f_entry); +} + +static inline void +ip6_mfilter_remove(struct ip6_mfilter_head *head, struct in6_mfilter *imf) +{ + + STAILQ_REMOVE(head, imf, in6_mfilter, im6f_entry); +} + +#define IP6_MFILTER_FOREACH(imf, head) \ + STAILQ_FOREACH(imf, head, im6f_entry) + +static inline size_t +ip6_mfilter_count(struct ip6_mfilter_head *head) +{ + struct in6_mfilter *imf; + size_t num = 0; + + STAILQ_FOREACH(imf, head, im6f_entry) + num++; + return (num); +} + /* * Legacy KAME IPv6 multicast membership descriptor. */ @@ -628,7 +687,6 @@ struct in6_multi_mship { * w/o breaking the ABI for ifmcstat. */ struct in6_multi { - LIST_ENTRY(in6_multi) in6m_entry; /* list glue */ struct in6_addr in6m_addr; /* IPv6 multicast address */ struct ifnet *in6m_ifp; /* back pointer to ifnet */ struct ifmultiaddr *in6m_ifma; /* back pointer to ifmultiaddr */ @@ -639,6 +697,7 @@ struct in6_multi { /* New fields for MLDv2 follow. */ struct mld_ifsoftc *in6m_mli; /* MLD info */ SLIST_ENTRY(in6_multi) in6m_nrele; /* to-be-released by MLD */ + SLIST_ENTRY(in6_multi) in6m_defer; /* deferred MLDv1 */ struct ip6_msource_tree in6m_srcs; /* tree of sources */ u_long in6m_nsrc; /* # of tree entries */ @@ -664,6 +723,8 @@ struct in6_multi { } in6m_st[2]; /* state at t0, t1 */ }; +void in6m_disconnect_locked(struct in6_multi_head *inmh, struct in6_multi *inm); + /* * Helper function to derive the filter mode on a source entry * from its internal counters. Predicates are: @@ -692,18 +753,40 @@ im6s_get_mode(const struct in6_multi *inm, const struct ip6_msource *ims, * consumers of IN_*_MULTI() macros should acquire the locks before * calling them; users of the in_{add,del}multi() functions should not. */ -extern struct mtx in6_multi_mtx; -#define IN6_MULTI_LOCK() mtx_lock(&in6_multi_mtx) -#define IN6_MULTI_UNLOCK() mtx_unlock(&in6_multi_mtx) -#define IN6_MULTI_LOCK_ASSERT() mtx_assert(&in6_multi_mtx, MA_OWNED) -#define IN6_MULTI_UNLOCK_ASSERT() mtx_assert(&in6_multi_mtx, MA_NOTOWNED) +extern struct mtx in6_multi_list_mtx; +extern struct sx in6_multi_sx; + +#define IN6_MULTI_LIST_LOCK() mtx_lock(&in6_multi_list_mtx) +#define IN6_MULTI_LIST_UNLOCK() mtx_unlock(&in6_multi_list_mtx) +#define IN6_MULTI_LIST_LOCK_ASSERT() mtx_assert(&in6_multi_list_mtx, MA_OWNED) +#define IN6_MULTI_LIST_UNLOCK_ASSERT() mtx_assert(&in6_multi_list_mtx, MA_NOTOWNED) + +#define IN6_MULTI_LOCK() sx_xlock(&in6_multi_sx) +#define IN6_MULTI_UNLOCK() sx_xunlock(&in6_multi_sx) +#define IN6_MULTI_LOCK_ASSERT() sx_assert(&in6_multi_sx, SA_XLOCKED) +#define IN6_MULTI_UNLOCK_ASSERT() sx_assert(&in6_multi_sx, SA_XUNLOCKED) + +/* + * Get the in6_multi pointer from a ifmultiaddr. + * Returns NULL if ifmultiaddr is no longer valid. + */ +static __inline struct in6_multi * +in6m_ifmultiaddr_get_inm(struct ifmultiaddr *ifma) +{ + + NET_EPOCH_ASSERT(); + + return ((ifma->ifma_addr->sa_family != AF_INET6 || + (ifma->ifma_flags & IFMA_F_ENQUEUED) == 0) ? NULL : + ifma->ifma_protospec); +} /* * Look up an in6_multi record for an IPv6 multicast address * on the interface ifp. * If no record found, return NULL. * - * SMPng: The IN6_MULTI_LOCK and IF_ADDR_LOCK on ifp must be held. + * SMPng: The IN6_MULTI_LOCK and must be held and must be in network epoch. */ static __inline struct in6_multi * in6m_lookup_locked(struct ifnet *ifp, const struct in6_addr *mcaddr) @@ -711,36 +794,31 @@ in6m_lookup_locked(struct ifnet *ifp, const struct in6_addr *mcaddr) struct ifmultiaddr *ifma; struct in6_multi *inm; - IN6_MULTI_LOCK_ASSERT(); - IF_ADDR_LOCK_ASSERT(ifp); - - inm = NULL; - TAILQ_FOREACH(ifma, &((ifp)->if_multiaddrs), ifma_link) { - if (ifma->ifma_addr->sa_family == AF_INET6) { - inm = (struct in6_multi *)ifma->ifma_protospec; - if (IN6_ARE_ADDR_EQUAL(&inm->in6m_addr, mcaddr)) - break; - inm = NULL; - } + CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + inm = in6m_ifmultiaddr_get_inm(ifma); + if (inm == NULL) + continue; + if (IN6_ARE_ADDR_EQUAL(&inm->in6m_addr, mcaddr)) + return (inm); } - return (inm); + return (NULL); } /* * Wrapper for in6m_lookup_locked(). * - * SMPng: Assumes that neithr the IN6_MULTI_LOCK() or IF_ADDR_LOCK() are held. + * SMPng: Assumes network epoch entered and that IN6_MULTI_LOCK() isn't held. */ static __inline struct in6_multi * in6m_lookup(struct ifnet *ifp, const struct in6_addr *mcaddr) { struct in6_multi *inm; - IN6_MULTI_LOCK(); - IF_ADDR_RLOCK(ifp); + NET_EPOCH_ASSERT(); + + IN6_MULTI_LIST_LOCK(); inm = in6m_lookup_locked(ifp, mcaddr); - IF_ADDR_RUNLOCK(ifp); - IN6_MULTI_UNLOCK(); + IN6_MULTI_LIST_UNLOCK(); return (inm); } @@ -750,36 +828,54 @@ static __inline void in6m_acquire_locked(struct in6_multi *inm) { - IN6_MULTI_LOCK_ASSERT(); + IN6_MULTI_LIST_LOCK_ASSERT(); ++inm->in6m_refcount; } +static __inline void +in6m_acquire(struct in6_multi *inm) +{ + IN6_MULTI_LIST_LOCK(); + in6m_acquire_locked(inm); + IN6_MULTI_LIST_UNLOCK(); +} + +static __inline void +in6m_rele_locked(struct in6_multi_head *inmh, struct in6_multi *inm) +{ + KASSERT(inm->in6m_refcount > 0, ("refcount == %d inm: %p", inm->in6m_refcount, inm)); + IN6_MULTI_LIST_LOCK_ASSERT(); + + if (--inm->in6m_refcount == 0) { + MPASS(inm->in6m_ifp == NULL); + inm->in6m_ifma->ifma_protospec = NULL; + MPASS(inm->in6m_ifma->ifma_llifma == NULL); + SLIST_INSERT_HEAD(inmh, inm, in6m_nrele); + } +} + struct ip6_moptions; struct sockopt; +struct inpcbinfo; +struct rib_head; /* Multicast KPIs. */ int im6o_mc_filter(const struct ip6_moptions *, const struct ifnet *, const struct sockaddr *, const struct sockaddr *); -int in6_mc_join(struct ifnet *, const struct in6_addr *, +int in6_joingroup(struct ifnet *, const struct in6_addr *, struct in6_mfilter *, struct in6_multi **, int); -int in6_mc_join_locked(struct ifnet *, const struct in6_addr *, - struct in6_mfilter *, struct in6_multi **, int); -int in6_mc_leave(struct in6_multi *, struct in6_mfilter *); -int in6_mc_leave_locked(struct in6_multi *, struct in6_mfilter *); +int in6_leavegroup(struct in6_multi *, struct in6_mfilter *); +int in6_leavegroup_locked(struct in6_multi *, struct in6_mfilter *); void in6m_clear_recorded(struct in6_multi *); void in6m_commit(struct in6_multi *); void in6m_print(const struct in6_multi *); int in6m_record_source(struct in6_multi *, const struct in6_addr *); -void in6m_release_locked(struct in6_multi *); +void in6m_release_list_deferred(struct in6_multi_head *); +void in6m_release_wait(void *); void ip6_freemoptions(struct ip6_moptions *); int ip6_getmoptions(struct inpcb *, struct sockopt *); int ip6_setmoptions(struct inpcb *, struct sockopt *); -/* Legacy KAME multicast KPIs. */ -struct in6_multi_mship * - in6_joingroup(struct ifnet *, struct in6_addr *, int *, int); -int in6_leavegroup(struct in6_multi_mship *); - /* flags to in6_update_ifa */ #define IN6_IFAUPDATE_DADDELAY 0x1 /* first time to configure an address */ @@ -791,11 +887,14 @@ int in6_update_ifa(struct ifnet *, struct in6_aliasreq *, void in6_prepare_ifra(struct in6_aliasreq *, const struct in6_addr *, const struct in6_addr *); void in6_purgeaddr(struct ifaddr *); +void in6_purgeifaddr(struct in6_ifaddr *); int in6if_do_dad(struct ifnet *); void in6_savemkludge(struct in6_ifaddr *); void *in6_domifattach(struct ifnet *); void in6_domifdetach(struct ifnet *, void *); int in6_domifmtu(struct ifnet *); +struct rib_head *in6_inithead(uint32_t fibnum); +void in6_detachhead(struct rib_head *rh); void in6_setmaxmtu(void); int in6_if2idlen(struct ifnet *); struct in6_ifaddr *in6ifa_ifpforlinklocal(struct ifnet *, int); @@ -819,13 +918,7 @@ void in6_newaddrmsg(struct in6_ifaddr *, int); /* * Extended API for IPv6 FIB support. */ -void in6_rtredirect(struct sockaddr *, struct sockaddr *, struct sockaddr *, - int, struct sockaddr *, u_int); -int in6_rtrequest(int, struct sockaddr *, struct sockaddr *, - struct sockaddr *, int, struct rtentry **, u_int); -void in6_rtalloc(struct route_in6 *, u_int); -void in6_rtalloc_ign(struct route_in6 *, u_long, u_int); -struct rtentry *in6_rtalloc1(struct sockaddr *, int, u_long, u_int); +struct mbuf *ip6_tryforward(struct mbuf *); #endif /* _KERNEL */ #endif /* _NETINET6_IN6_VAR_H_ */ diff --git a/tools/compat/include/netinet6/ip6_mroute.h b/tools/compat/include/netinet6/ip6_mroute.h index 51e1d496a..40a857707 100644 --- a/tools/compat/include/netinet6/ip6_mroute.h +++ b/tools/compat/include/netinet6/ip6_mroute.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (C) 1998 WIDE Project. * All rights reserved. * diff --git a/tools/compat/include/netinet6/ip6_var.h b/tools/compat/include/netinet6/ip6_var.h index e52a32068..de7a938a3 100644 --- a/tools/compat/include/netinet6/ip6_var.h +++ b/tools/compat/include/netinet6/ip6_var.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * @@ -41,7 +43,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -64,39 +66,29 @@ #ifndef _NETINET6_IP6_VAR_H_ #define _NETINET6_IP6_VAR_H_ +#include + +#ifdef _KERNEL +struct ip6asfrag; /* frag6.c */ +TAILQ_HEAD(ip6fraghead, ip6asfrag); + /* * IP6 reassembly queue structure. Each fragment * being reassembled is attached to one of these structures. */ struct ip6q { - struct ip6asfrag *ip6q_down; - struct ip6asfrag *ip6q_up; + struct ip6fraghead ip6q_frags; u_int32_t ip6q_ident; u_int8_t ip6q_nxt; u_int8_t ip6q_ecn; u_int8_t ip6q_ttl; struct in6_addr ip6q_src, ip6q_dst; - struct ip6q *ip6q_next; - struct ip6q *ip6q_prev; + TAILQ_ENTRY(ip6q) ip6q_tq; int ip6q_unfrglen; /* len of unfragmentable part */ -#ifdef notyet - u_char *ip6q_nxtp; -#endif int ip6q_nfrag; /* # of fragments */ struct label *ip6q_label; }; - -struct ip6asfrag { - struct ip6asfrag *ip6af_down; - struct ip6asfrag *ip6af_up; - struct mbuf *ip6af_m; - int ip6af_offset; /* offset in ip6af_m to next header */ - int ip6af_frglen; /* fragmentable part length */ - int ip6af_off; /* fragment offset */ - u_int16_t ip6af_mff; /* more fragment bit in frag off */ -}; - -#define IP6_REASS_MBUF(ip6af) (*(struct mbuf **)&((ip6af)->ip6af_m)) +#endif /* _KERNEL */ /* * IP6 reinjecting structure. @@ -106,6 +98,7 @@ struct ip6_direct_ctx { uint32_t ip6dc_off; /* offset to next header */ }; +#if defined(_NETINET6_IN6_VAR_H_) && defined(_KERNEL) /* * Structure attached to inpcb.in6p_moptions and * passed to ip6_output when IPv6 multicast options are in use. @@ -115,12 +108,11 @@ struct ip6_moptions { struct ifnet *im6o_multicast_ifp; /* ifp for outgoing multicasts */ u_char im6o_multicast_hlim; /* hoplimit for outgoing multicasts */ u_char im6o_multicast_loop; /* 1 >= hear sends if a member */ - u_short im6o_num_memberships; /* no. memberships this socket */ - u_short im6o_max_memberships; /* max memberships this socket */ - struct in6_multi **im6o_membership; /* group memberships */ - struct in6_mfilter *im6o_mfilters; /* source filters */ + struct ip6_mfilter_head im6o_head; /* group membership list */ }; - +#else +struct ip6_moptions; +#endif /* * Control options for outgoing packets */ @@ -203,6 +195,7 @@ struct ip6stat { uint64_t ip6s_localout; /* total ip packets generated here */ uint64_t ip6s_odropped; /* lost packets due to nobufs, etc. */ uint64_t ip6s_reassembled; /* total packets reassembled ok */ + uint64_t ip6s_atomicfrags; /* atomic fragments */ uint64_t ip6s_fragmented; /* datagrams successfully fragmented */ uint64_t ip6s_ofragments; /* output fragments created */ uint64_t ip6s_cantfrag; /* don't fragment flag was set, etc. */ @@ -294,10 +287,6 @@ VNET_DECLARE(int, ip6_v6only); VNET_DECLARE(struct socket *, ip6_mrouter); /* multicast routing daemon */ VNET_DECLARE(int, ip6_sendredirects); /* send IP redirects when forwarding? */ -VNET_DECLARE(int, ip6_maxfragpackets); /* Maximum packets in reassembly - * queue */ -VNET_DECLARE(int, ip6_maxfrags); /* Maximum fragments in reassembly - * queue */ VNET_DECLARE(int, ip6_accept_rtadv); /* Acts as a host not a router */ VNET_DECLARE(int, ip6_no_radr); /* No defroute from RA */ VNET_DECLARE(int, ip6_norbit_raif); /* Disable R-bit in NA on RA @@ -311,8 +300,6 @@ VNET_DECLARE(int, ip6_hdrnestlimit); /* upper limit of # of extension VNET_DECLARE(int, ip6_dad_count); /* DupAddrDetectionTransmits */ #define V_ip6_mrouter VNET(ip6_mrouter) #define V_ip6_sendredirects VNET(ip6_sendredirects) -#define V_ip6_maxfragpackets VNET(ip6_maxfragpackets) -#define V_ip6_maxfrags VNET(ip6_maxfrags) #define V_ip6_accept_rtadv VNET(ip6_accept_rtadv) #define V_ip6_no_radr VNET(ip6_no_radr) #define V_ip6_norbit_raif VNET(ip6_norbit_raif) @@ -338,13 +325,20 @@ VNET_DECLARE(int, ip6_use_defzone); /* Whether to use the default scope * zone when unspecified */ #define V_ip6_use_defzone VNET(ip6_use_defzone) -VNET_DECLARE (struct pfil_head, inet6_pfil_hook); /* packet filter hooks */ -#define V_inet6_pfil_hook VNET(inet6_pfil_hook) +VNET_DECLARE(struct pfil_head *, inet6_pfil_head); +#define V_inet6_pfil_head VNET(inet6_pfil_head) +#define PFIL_INET6_NAME "inet6" + #ifdef IPSTEALTH VNET_DECLARE(int, ip6stealth); #define V_ip6stealth VNET(ip6stealth) #endif +#ifdef EXPERIMENTAL +VNET_DECLARE(int, nd6_ignore_ipv6_only_ra); +#define V_nd6_ignore_ipv6_only_ra VNET(nd6_ignore_ipv6_only_ra) +#endif + extern struct pr_usrreqs rip6_usrreqs; struct sockopt; @@ -362,7 +356,7 @@ void ip6_direct_input(struct mbuf *); void ip6_freepcbopts(struct ip6_pktopts *); int ip6_unknown_opt(u_int8_t *, struct mbuf *, int); -char * ip6_get_prevhdr(const struct mbuf *, int); +int ip6_get_prevhdr(const struct mbuf *, int); int ip6_nexthdr(const struct mbuf *, int, int, int *); int ip6_lasthdr(const struct mbuf *, int, int, int *); @@ -400,6 +394,7 @@ int ip6_fragment(struct ifnet *, struct mbuf *, int, u_char, int, int route6_input(struct mbuf **, int *, int); void frag6_init(void); +void frag6_destroy(void); int frag6_input(struct mbuf **, int *, int); void frag6_slowtimo(void); void frag6_drain(void); @@ -421,10 +416,7 @@ int in6_selectsrc_addr(uint32_t, const struct in6_addr *, uint32_t, struct ifnet *, struct in6_addr *, int *); int in6_selectroute(struct sockaddr_in6 *, struct ip6_pktopts *, struct ip6_moptions *, struct route_in6 *, struct ifnet **, - struct rtentry **); -int in6_selectroute_fib(struct sockaddr_in6 *, struct ip6_pktopts *, - struct ip6_moptions *, struct route_in6 *, struct ifnet **, - struct rtentry **, u_int); + struct nhop_object **, u_int, uint32_t); u_int32_t ip6_randomid(void); u_int32_t ip6_randomflowlabel(void); void in6_delayed_cksum(struct mbuf *m, uint32_t plen, u_short offset); diff --git a/tools/compat/include/netinet6/ip_fw_nat64.h b/tools/compat/include/netinet6/ip_fw_nat64.h new file mode 100644 index 000000000..40e344113 --- /dev/null +++ b/tools/compat/include/netinet6/ip_fw_nat64.h @@ -0,0 +1,210 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015-2019 Yandex LLC + * Copyright (c) 2015 Alexander V. Chernikov + * Copyright (c) 2015-2019 Andrey V. Elsukov + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _NETINET6_IP_FW_NAT64_H_ +#define _NETINET6_IP_FW_NAT64_H_ + +struct ipfw_nat64stl_stats { + uint64_t opcnt64; /* 6to4 of packets translated */ + uint64_t opcnt46; /* 4to6 of packets translated */ + uint64_t ofrags; /* number of fragments generated */ + uint64_t ifrags; /* number of fragments received */ + uint64_t oerrors; /* number of output errors */ + uint64_t noroute4; + uint64_t noroute6; + uint64_t noproto; /* Protocol not supported */ + uint64_t nomem; /* mbuf allocation failed */ + uint64_t dropped; /* dropped due to some errors */ +}; + +struct ipfw_nat64clat_stats { + uint64_t opcnt64; /* 6to4 of packets translated */ + uint64_t opcnt46; /* 4to6 of packets translated */ + uint64_t ofrags; /* number of fragments generated */ + uint64_t ifrags; /* number of fragments received */ + uint64_t oerrors; /* number of output errors */ + uint64_t noroute4; + uint64_t noroute6; + uint64_t noproto; /* Protocol not supported */ + uint64_t nomem; /* mbuf allocation failed */ + uint64_t dropped; /* dropped due to some errors */ +}; + +struct ipfw_nat64lsn_stats { + uint64_t opcnt64; /* 6to4 of packets translated */ + uint64_t opcnt46; /* 4to6 of packets translated */ + uint64_t ofrags; /* number of fragments generated */ + uint64_t ifrags; /* number of fragments received */ + uint64_t oerrors; /* number of output errors */ + uint64_t noroute4; + uint64_t noroute6; + uint64_t noproto; /* Protocol not supported */ + uint64_t nomem; /* mbuf allocation failed */ + uint64_t dropped; /* dropped due to some errors */ + + uint64_t nomatch4; /* No addr/port match */ + uint64_t jcalls; /* Number of job handler calls */ + uint64_t jrequests; /* Number of job requests */ + uint64_t jhostsreq; /* Number of job host requests */ + uint64_t jportreq; /* Number of portgroup requests */ + uint64_t jhostfails; /* Number of failed host allocs */ + uint64_t jportfails; /* Number of failed portgroup allocs */ + uint64_t jreinjected; /* Number of packets reinjected to q */ + uint64_t jmaxlen; /* Max queue length reached */ + uint64_t jnomem; /* No memory to alloc queue item */ + + uint64_t screated; /* Number of states created */ + uint64_t sdeleted; /* Number of states deleted */ + uint64_t spgcreated; /* Number of portgroups created */ + uint64_t spgdeleted; /* Number of portgroups deleted */ + uint64_t hostcount; /* Number of hosts */ + uint64_t tcpchunks; /* Number of TCP chunks */ + uint64_t udpchunks; /* Number of UDP chunks */ + uint64_t icmpchunks; /* Number of ICMP chunks */ + + uint64_t _reserved[4]; +}; + +#define NAT64_LOG 0x0001 /* Enable logging via BPF */ +#define NAT64_ALLOW_PRIVATE 0x0002 /* Allow private IPv4 address + * translation + */ +typedef struct _ipfw_nat64stl_cfg { + char name[64]; /* NAT name */ + ipfw_obj_ntlv ntlv6; /* object name tlv */ + ipfw_obj_ntlv ntlv4; /* object name tlv */ + struct in6_addr prefix6; /* NAT64 prefix */ + uint8_t plen6; /* Prefix length */ + uint8_t set; /* Named instance set [0..31] */ + uint8_t spare[2]; + uint32_t flags; +} ipfw_nat64stl_cfg; + +typedef struct _ipfw_nat64clat_cfg { + char name[64]; /* NAT name */ + struct in6_addr plat_prefix; /* NAT64 (PLAT) prefix */ + struct in6_addr clat_prefix; /* Client (CLAT) prefix */ + uint8_t plat_plen; /* PLAT Prefix length */ + uint8_t clat_plen; /* CLAT Prefix length */ + uint8_t set; /* Named instance set [0..31] */ + uint8_t spare; + uint32_t flags; +} ipfw_nat64clat_cfg; + +/* + * NAT64LSN default configuration values + */ +#define NAT64LSN_MAX_PORTS 2048 /* Unused */ +#define NAT64LSN_JMAXLEN 2048 /* Max outstanding requests. */ +#define NAT64LSN_TCP_SYN_AGE 10 /* State's TTL after SYN received. */ +#define NAT64LSN_TCP_EST_AGE (2 * 3600) /* TTL for established connection */ +#define NAT64LSN_TCP_FIN_AGE 180 /* State's TTL after FIN/RST received */ +#define NAT64LSN_UDP_AGE 120 /* TTL for UDP states */ +#define NAT64LSN_ICMP_AGE 60 /* TTL for ICMP states */ +#define NAT64LSN_HOST_AGE 3600 /* TTL for stale host entry */ +#define NAT64LSN_PG_AGE 900 /* TTL for stale ports groups */ + +typedef struct _ipfw_nat64lsn_cfg { + char name[64]; /* NAT name */ + uint32_t flags; + + uint32_t max_ports; /* Unused */ + uint32_t agg_prefix_len; /* Unused */ + uint32_t agg_prefix_max; /* Unused */ + + struct in_addr prefix4; + uint16_t plen4; /* Prefix length */ + uint16_t plen6; /* Prefix length */ + struct in6_addr prefix6; /* NAT64 prefix */ + uint32_t jmaxlen; /* Max jobqueue length */ + + uint16_t min_port; /* Unused */ + uint16_t max_port; /* Unused */ + + uint16_t nh_delete_delay;/* Stale host delete delay */ + uint16_t pg_delete_delay;/* Stale portgroup delete delay */ + uint16_t st_syn_ttl; /* TCP syn expire */ + uint16_t st_close_ttl; /* TCP fin expire */ + uint16_t st_estab_ttl; /* TCP established expire */ + uint16_t st_udp_ttl; /* UDP expire */ + uint16_t st_icmp_ttl; /* ICMP expire */ + uint8_t set; /* Named instance set [0..31] */ + uint8_t states_chunks; /* Number of states chunks per PG */ +} ipfw_nat64lsn_cfg; + +typedef struct _ipfw_nat64lsn_state { + struct in_addr daddr; /* Remote IPv4 address */ + uint16_t dport; /* Remote destination port */ + uint16_t aport; /* Local alias port */ + uint16_t sport; /* Source port */ + uint8_t flags; /* State flags */ + uint8_t spare[3]; + uint16_t idle; /* Last used time */ +} ipfw_nat64lsn_state; + +typedef struct _ipfw_nat64lsn_stg { + uint64_t next_idx; /* next state index */ + struct in_addr alias4; /* IPv4 alias address */ + uint8_t proto; /* protocol */ + uint8_t flags; + uint16_t spare; + struct in6_addr host6; /* Bound IPv6 host */ + uint32_t count; /* Number of states */ + uint32_t spare2; +} ipfw_nat64lsn_stg; + +typedef struct _ipfw_nat64lsn_state_v1 { + struct in6_addr host6; /* Bound IPv6 host */ + struct in_addr daddr; /* Remote IPv4 address */ + uint16_t dport; /* Remote destination port */ + uint16_t aport; /* Local alias port */ + uint16_t sport; /* Source port */ + uint16_t spare; + uint16_t idle; /* Last used time */ + uint8_t flags; /* State flags */ + uint8_t proto; /* protocol */ +} ipfw_nat64lsn_state_v1; + +typedef struct _ipfw_nat64lsn_stg_v1 { + union nat64lsn_pgidx { + uint64_t index; + struct { + uint8_t chunk; /* states chunk */ + uint8_t proto; /* protocol */ + uint16_t port; /* base port */ + in_addr_t addr; /* alias address */ + }; + } next; /* next state index */ + struct in_addr alias4; /* IPv4 alias address */ + uint32_t count; /* Number of states */ +} ipfw_nat64lsn_stg_v1; + +#endif /* _NETINET6_IP_FW_NAT64_H_ */ diff --git a/tools/compat/include/netinet6/ip_fw_nptv6.h b/tools/compat/include/netinet6/ip_fw_nptv6.h new file mode 100644 index 000000000..d777db98d --- /dev/null +++ b/tools/compat/include/netinet6/ip_fw_nptv6.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2016 Yandex LLC + * Copyright (c) 2016 Andrey V. Elsukov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _NETINET6_IP_FW_NPTV6_H_ +#define _NETINET6_IP_FW_NPTV6_H_ + +struct ipfw_nptv6_stats { + uint64_t in2ex; /* Int->Ext packets translated */ + uint64_t ex2in; /* Ext->Int packets translated */ + uint64_t dropped; /* dropped due to some errors */ + uint64_t reserved[5]; +}; + +typedef struct _ipfw_nptv6_cfg { + char name[64]; /* NPTv6 instance name */ + struct in6_addr internal; /* NPTv6 internal prefix */ + union { + struct in6_addr external; /* NPTv6 external prefix */ + char if_name[IF_NAMESIZE]; + }; + uint8_t plen; /* Prefix length */ + uint8_t set; /* Named instance set [0..31] */ + uint8_t spare[2]; + uint32_t flags; +#define NPTV6_DYNAMIC_PREFIX 1 /* Use dynamic external prefix */ +} ipfw_nptv6_cfg; + +#endif /* _NETINET6_IP_FW_NPTV6_H_ */ diff --git a/tools/compat/include/netinet6/nd6.h b/tools/compat/include/netinet6/nd6.h index 33ac4386b..a64c786ef 100644 --- a/tools/compat/include/netinet6/nd6.h +++ b/tools/compat/include/netinet6/nd6.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * @@ -88,6 +90,12 @@ struct nd_ifinfo { #define ND6_IFF_NO_RADR 0x40 #define ND6_IFF_NO_PREFER_IFACE 0x80 /* XXX: not related to ND. */ #define ND6_IFF_NO_DAD 0x100 +#ifdef EXPERIMENTAL +/* XXX: not related to ND. */ +#define ND6_IFF_IPV6_ONLY 0x200 /* draft-ietf-6man-ipv6only-flag */ +#define ND6_IFF_IPV6_ONLY_MANUAL 0x400 +#define ND6_IFF_IPV6_ONLY_MASK (ND6_IFF_IPV6_ONLY|ND6_IFF_IPV6_ONLY_MANUAL) +#endif #ifdef _KERNEL #define ND_IFINFO(ifp) \ @@ -108,19 +116,7 @@ struct in6_nbrinfo { int expire; /* lifetime for NDP state transition */ }; -#define DRLSTSIZ 10 -#define PRLSTSIZ 10 -struct in6_drlist { - char ifname[IFNAMSIZ]; - struct { - struct in6_addr rtaddr; - u_char flags; - u_short rtlifetime; - u_long expire; - u_short if_index; - } defrouter[DRLSTSIZ]; -}; - +/* Sysctls, shared with user space. */ struct in6_defrouter { struct sockaddr_in6 rtaddr; u_char flags; @@ -129,40 +125,6 @@ struct in6_defrouter { u_short if_index; }; -#ifdef _KERNEL -struct in6_oprlist { - char ifname[IFNAMSIZ]; - struct { - struct in6_addr prefix; - struct prf_ra raflags; - u_char prefixlen; - u_char origin; - u_long vltime; - u_long pltime; - u_long expire; - u_short if_index; - u_short advrtrs; /* number of advertisement routers */ - struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */ - } prefix[PRLSTSIZ]; -}; -#endif - -struct in6_prlist { - char ifname[IFNAMSIZ]; - struct { - struct in6_addr prefix; - struct prf_ra raflags; - u_char prefixlen; - u_char origin; - u_int32_t vltime; - u_int32_t pltime; - time_t expire; - u_short if_index; - u_short advrtrs; /* number of advertisement routers */ - struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */ - } prefix[PRLSTSIZ]; -}; - struct in6_prefix { struct sockaddr_in6 prefix; struct prf_ra raflags; @@ -231,7 +193,6 @@ struct in6_ndifreq { (((MIN_RANDOM_FACTOR * (x >> 10)) + (arc4random() & \ ((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000) -TAILQ_HEAD(nd_drhead, nd_defrouter); struct nd_defrouter { TAILQ_ENTRY(nd_defrouter) dr_entry; struct in6_addr rtaddr; @@ -256,7 +217,7 @@ struct nd_prefixctl { struct prf_ra ndpr_flags; }; - +LIST_HEAD(nd_prhead, nd_prefix); struct nd_prefix { struct ifnet *ndpr_ifp; LIST_ENTRY(nd_prefix) ndpr_entry; @@ -275,7 +236,8 @@ struct nd_prefix { /* list of routers that advertise the prefix: */ LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs; u_char ndpr_plen; - int ndpr_refcnt; /* reference couter from addresses */ + int ndpr_addrcnt; /* count of derived addresses */ + volatile u_int ndpr_refcnt; }; #define ndpr_raf ndpr_flags @@ -283,39 +245,11 @@ struct nd_prefix { #define ndpr_raf_auto ndpr_flags.autonomous #define ndpr_raf_router ndpr_flags.router -/* - * Message format for use in obtaining information about prefixes - * from inet6 sysctl function - */ -struct inet6_ndpr_msghdr { - u_short inpm_msglen; /* to skip over non-understood messages */ - u_char inpm_version; /* future binary compatibility */ - u_char inpm_type; /* message type */ - struct in6_addr inpm_prefix; - u_long prm_vltim; - u_long prm_pltime; - u_long prm_expire; - u_long prm_preferred; - struct in6_prflags prm_flags; - u_short prm_index; /* index for associated ifp */ - u_char prm_plen; /* length of prefix in bits */ -}; - -#define prm_raf_onlink prm_flags.prf_ra.onlink -#define prm_raf_auto prm_flags.prf_ra.autonomous - -#define prm_statef_onlink prm_flags.prf_state.onlink - -#define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid -#define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd - struct nd_pfxrouter { LIST_ENTRY(nd_pfxrouter) pfr_entry; struct nd_defrouter *router; }; -LIST_HEAD(nd_prhead, nd_prefix); - #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_IP6NDP); #endif @@ -328,7 +262,6 @@ VNET_DECLARE(int, nd6_mmaxtries); VNET_DECLARE(int, nd6_useloopback); VNET_DECLARE(int, nd6_maxnudhint); VNET_DECLARE(int, nd6_gctimer); -VNET_DECLARE(struct nd_drhead, nd_defrouter); VNET_DECLARE(struct nd_prhead, nd_prefix); VNET_DECLARE(int, nd6_debug); VNET_DECLARE(int, nd6_onlink_ns_rfc4861); @@ -339,24 +272,36 @@ VNET_DECLARE(int, nd6_onlink_ns_rfc4861); #define V_nd6_useloopback VNET(nd6_useloopback) #define V_nd6_maxnudhint VNET(nd6_maxnudhint) #define V_nd6_gctimer VNET(nd6_gctimer) -#define V_nd_defrouter VNET(nd_defrouter) #define V_nd_prefix VNET(nd_prefix) #define V_nd6_debug VNET(nd6_debug) #define V_nd6_onlink_ns_rfc4861 VNET(nd6_onlink_ns_rfc4861) /* Lock for the prefix and default router lists. */ VNET_DECLARE(struct rwlock, nd6_lock); +VNET_DECLARE(uint64_t, nd6_list_genid); #define V_nd6_lock VNET(nd6_lock) +#define V_nd6_list_genid VNET(nd6_list_genid) #define ND6_RLOCK() rw_rlock(&V_nd6_lock) #define ND6_RUNLOCK() rw_runlock(&V_nd6_lock) #define ND6_WLOCK() rw_wlock(&V_nd6_lock) #define ND6_WUNLOCK() rw_wunlock(&V_nd6_lock) +#define ND6_TRY_UPGRADE() rw_try_upgrade(&V_nd6_lock) #define ND6_WLOCK_ASSERT() rw_assert(&V_nd6_lock, RA_WLOCKED) #define ND6_RLOCK_ASSERT() rw_assert(&V_nd6_lock, RA_RLOCKED) #define ND6_LOCK_ASSERT() rw_assert(&V_nd6_lock, RA_LOCKED) #define ND6_UNLOCK_ASSERT() rw_assert(&V_nd6_lock, RA_UNLOCKED) +/* Mutex for prefix onlink/offlink transitions. */ +VNET_DECLARE(struct mtx, nd6_onlink_mtx); +#define V_nd6_onlink_mtx VNET(nd6_onlink_mtx) + +#define ND6_ONLINK_LOCK() mtx_lock(&V_nd6_onlink_mtx) +#define ND6_ONLINK_TRYLOCK() mtx_trylock(&V_nd6_onlink_mtx) +#define ND6_ONLINK_UNLOCK() mtx_unlock(&V_nd6_onlink_mtx) +#define ND6_ONLINK_LOCK_ASSERT() mtx_assert(&V_nd6_onlink_mtx, MA_OWNED) +#define ND6_ONLINK_UNLOCK_ASSERT() mtx_assert(&V_nd6_onlink_mtx, MA_NOTOWNED) + #define nd6log(x) do { if (V_nd6_debug) log x; } while (/*CONSTCOND*/ 0) /* nd6_rtr.c */ @@ -420,7 +365,6 @@ void nd6_option_init(void *, int, union nd_opts *); struct nd_opt_hdr *nd6_option(union nd_opts *); int nd6_options(union nd_opts *); struct llentry *nd6_lookup(const struct in6_addr *, int, struct ifnet *); -struct llentry *nd6_alloc(const struct in6_addr *, int, struct ifnet *); void nd6_setmtu(struct ifnet *); void nd6_llinfo_setstate(struct llentry *lle, int newstate); void nd6_timer(void *); @@ -434,13 +378,18 @@ void nd6_cache_lladdr(struct ifnet *, struct in6_addr *, char *, int, int, int); void nd6_grab_holdchain(struct llentry *, struct mbuf **, struct sockaddr_in6 *); -int nd6_flush_holdchain(struct ifnet *, struct ifnet *, struct mbuf *, +int nd6_flush_holdchain(struct ifnet *, struct mbuf *, struct sockaddr_in6 *); int nd6_add_ifa_lle(struct in6_ifaddr *); void nd6_rem_ifa_lle(struct in6_ifaddr *, int); int nd6_output_ifp(struct ifnet *, struct ifnet *, struct mbuf *, struct sockaddr_in6 *, struct route *); +struct rib_head; +struct rib_cmd_info; +void nd6_subscription_cb(struct rib_head *rnh, struct rib_cmd_info *rc, + void *arg); + /* nd6_nbr.c */ void nd6_na_input(struct mbuf *, int, int); void nd6_na_output(struct ifnet *, const struct in6_addr *, @@ -456,19 +405,27 @@ void nd6_dad_stop(struct ifaddr *); /* nd6_rtr.c */ void nd6_rs_input(struct mbuf *, int, int); void nd6_ra_input(struct mbuf *, int, int); +void nd6_ifnet_link_event(void *, struct ifnet *, int); +struct nd_defrouter *defrouter_lookup(const struct in6_addr *, struct ifnet *); +struct nd_defrouter *defrouter_lookup_locked(const struct in6_addr *, + struct ifnet *); void defrouter_reset(void); -void defrouter_select(void); -void defrouter_ref(struct nd_defrouter *); +void defrouter_select_fib(int fibnum); void defrouter_rele(struct nd_defrouter *); bool defrouter_remove(struct in6_addr *, struct ifnet *); -void defrouter_unlink(struct nd_defrouter *, struct nd_drhead *); -void defrouter_del(struct nd_defrouter *); -void prelist_remove(struct nd_prefix *); +bool nd6_defrouter_list_empty(void); +void nd6_defrouter_flush_all(void); +void nd6_defrouter_purge(struct ifnet *); +void nd6_defrouter_timer(void); +void nd6_defrouter_init(void); int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *, - struct nd_prefix **); + struct nd_prefix **); +void nd6_prefix_unlink(struct nd_prefix *, struct nd_prhead *); +void nd6_prefix_del(struct nd_prefix *); +void nd6_prefix_ref(struct nd_prefix *); +void nd6_prefix_rele(struct nd_prefix *); +int nd6_prefix_offlink(struct nd_prefix *); void pfxlist_onlink_check(void); -struct nd_defrouter *defrouter_lookup(struct in6_addr *, struct ifnet *); -struct nd_defrouter *defrouter_lookup_locked(struct in6_addr *, struct ifnet *); struct nd_prefix *nd6_prefix_lookup(struct nd_prefixctl *); void rt6_flush(struct in6_addr *, struct ifnet *); int nd6_setdefaultiface(int); diff --git a/tools/compat/include/netinet6/pim6_var.h b/tools/compat/include/netinet6/pim6_var.h index 7f9262bbc..7288c67ee 100644 --- a/tools/compat/include/netinet6/pim6_var.h +++ b/tools/compat/include/netinet6/pim6_var.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (C) 1998 WIDE Project. * All rights reserved. * @@ -51,10 +53,6 @@ struct pim6stat { uint64_t pim6s_snd_registers; /* sent registers */ }; -#if (defined(KERNEL)) || (defined(_KERNEL)) -int pim6_input(struct mbuf **, int*, int); -#endif /* KERNEL */ - /* * Identifiers for PIM sysctl nodes */ diff --git a/tools/compat/include/netinet6/raw_ip6.h b/tools/compat/include/netinet6/raw_ip6.h index 5eec5fffd..e2dcac36d 100644 --- a/tools/compat/include/netinet6/raw_ip6.h +++ b/tools/compat/include/netinet6/raw_ip6.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (C) 2001 WIDE Project. * All rights reserved. * diff --git a/tools/compat/include/sys/_domainset.h b/tools/compat/include/sys/_domainset.h new file mode 100644 index 000000000..5685d532a --- /dev/null +++ b/tools/compat/include/sys/_domainset.h @@ -0,0 +1,60 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2017, Jeffrey Roberson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SYS__DOMAINSET_H_ +#define _SYS__DOMAINSET_H_ + +#include + +#ifdef _KERNEL +#define DOMAINSET_SETSIZE MAXMEMDOM +#endif + +#define DOMAINSET_MAXSIZE 256 + +#ifndef DOMAINSET_SETSIZE +#define DOMAINSET_SETSIZE DOMAINSET_MAXSIZE +#endif + +BITSET_DEFINE(_domainset, DOMAINSET_SETSIZE); +typedef struct _domainset domainset_t; + +/* + * This structure is intended to be embedded in objects which have policy + * attributes. Each object keeps its own iterator so round-robin is + * synchronized and accurate. + */ +struct domainset; +struct domainset_ref { + struct domainset * volatile dr_policy; + unsigned int dr_iter; +}; + +#endif /* !_SYS__DOMAINSET_H_ */ diff --git a/tools/compat/include/sys/_smr.h b/tools/compat/include/sys/_smr.h new file mode 100644 index 000000000..272bf8c07 --- /dev/null +++ b/tools/compat/include/sys/_smr.h @@ -0,0 +1,50 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2019, 2020 Jeffrey Roberson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#ifndef _SYS__SMR_H_ +#define _SYS__SMR_H_ + +typedef uint32_t smr_seq_t; +typedef int32_t smr_delta_t; +typedef struct smr *smr_t; + +#define SMR_ENTERED(smr) \ + (curthread->td_critnest != 0 && zpcpu_get((smr))->c_seq != SMR_SEQ_INVALID) + +#define SMR_ASSERT_ENTERED(smr) \ + KASSERT(SMR_ENTERED(smr), ("Not in smr section")) + +#define SMR_ASSERT_NOT_ENTERED(smr) \ + KASSERT(!SMR_ENTERED(smr), ("In smr section.")); + +#define SMR_ASSERT(ex, fn) \ + KASSERT((ex), (fn ": Assertion " #ex " failed at %s:%d", __FILE__, __LINE__)) + +#endif /* __SYS_SMR_H_ */ diff --git a/tools/compat/include/sys/_types.h b/tools/compat/include/sys/_types.h index 5d8c9130f..e10a32114 100644 --- a/tools/compat/include/sys/_types.h +++ b/tools/compat/include/sys/_types.h @@ -117,4 +117,9 @@ typedef __lwpid_t lwpid_t; /* Thread ID (a.k.a. LWP) */ #define _LWPID_T_DECLARED #endif +typedef __uint64_t kpaddr_t; +typedef __uint64_t kvaddr_t; +typedef __uint64_t ksize_t; +typedef __int64_t kssize_t; + #endif /* !_COMPAT_SYS__TYPES_H_ */ diff --git a/tools/compat/include/sys/ck.h b/tools/compat/include/sys/ck.h new file mode 100644 index 000000000..3bfce70c8 --- /dev/null +++ b/tools/compat/include/sys/ck.h @@ -0,0 +1,13 @@ +/* + * $FreeBSD$ + */ +#ifdef _KERNEL +#include +#include +#else +#include +#define CK_STAILQ_HEAD STAILQ_HEAD +#define CK_STAILQ_ENTRY STAILQ_ENTRY +#define CK_LIST_HEAD LIST_HEAD +#define CK_LIST_ENTRY LIST_ENTRY +#endif diff --git a/tools/compat/include/sys/epoch.h b/tools/compat/include/sys/epoch.h new file mode 100644 index 000000000..5c1282df5 --- /dev/null +++ b/tools/compat/include/sys/epoch.h @@ -0,0 +1,112 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2018, Matthew Macy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SYS_EPOCH_H_ +#define _SYS_EPOCH_H_ + +struct epoch_context { + void *data[2]; +} __attribute__((__aligned__(sizeof(void *)))); + +typedef struct epoch_context *epoch_context_t; +typedef void epoch_callback_t(epoch_context_t); + +#ifdef _KERNEL +#include +#include +#include + +struct epoch; +typedef struct epoch *epoch_t; + +#define EPOCH_PREEMPT 0x1 +#define EPOCH_LOCKED 0x2 + +extern epoch_t global_epoch; +extern epoch_t global_epoch_preempt; + +struct epoch_tracker { + TAILQ_ENTRY(epoch_tracker) et_link; + struct thread *et_td; + ck_epoch_section_t et_section; +#ifdef EPOCH_TRACE + struct epoch *et_epoch; + SLIST_ENTRY(epoch_tracker) et_tlink; + const char *et_file; + int et_line; +#endif +} __attribute__((__aligned__(sizeof(void *)))); +typedef struct epoch_tracker *epoch_tracker_t; + +epoch_t epoch_alloc(const char *name, int flags); +void epoch_free(epoch_t epoch); +void epoch_wait(epoch_t epoch); +void epoch_wait_preempt(epoch_t epoch); +void epoch_drain_callbacks(epoch_t epoch); +void epoch_call(epoch_t epoch, epoch_callback_t cb, epoch_context_t ctx); +int in_epoch(epoch_t epoch); +int in_epoch_verbose(epoch_t epoch, int dump_onfail); +DPCPU_DECLARE(int, epoch_cb_count); +DPCPU_DECLARE(struct grouptask, epoch_cb_task); + +#ifdef EPOCH_TRACE +#define EPOCH_FILE_LINE , const char *file, int line +#else +#define EPOCH_FILE_LINE +#endif + +void _epoch_enter_preempt(epoch_t epoch, epoch_tracker_t et EPOCH_FILE_LINE); +void _epoch_exit_preempt(epoch_t epoch, epoch_tracker_t et EPOCH_FILE_LINE); +#ifdef EPOCH_TRACE +void epoch_trace_list(struct thread *); +#define epoch_enter_preempt(epoch, et) _epoch_enter_preempt(epoch, et, __FILE__, __LINE__) +#define epoch_exit_preempt(epoch, et) _epoch_exit_preempt(epoch, et, __FILE__, __LINE__) +#else +#define epoch_enter_preempt(epoch, et) _epoch_enter_preempt(epoch, et) +#define epoch_exit_preempt(epoch, et) _epoch_exit_preempt(epoch, et) +#endif +void epoch_enter(epoch_t epoch); +void epoch_exit(epoch_t epoch); + +/* + * Globally recognized epochs in the FreeBSD kernel. + */ +/* Network preemptible epoch, declared in sys/net/if.c. */ +extern epoch_t net_epoch_preempt; +#define NET_EPOCH_ENTER(et) epoch_enter_preempt(net_epoch_preempt, &(et)) +#define NET_EPOCH_EXIT(et) epoch_exit_preempt(net_epoch_preempt, &(et)) +#define NET_EPOCH_WAIT() epoch_wait_preempt(net_epoch_preempt) +#define NET_EPOCH_CALL(f, c) epoch_call(net_epoch_preempt, (f), (c)) +#define NET_EPOCH_ASSERT() MPASS(in_epoch(net_epoch_preempt)) +#define NET_TASK_INIT(t, p, f, c) TASK_INIT_FLAGS(t, p, f, c, TASK_NETWORK) +#define NET_GROUPTASK_INIT(gtask, prio, func, ctx) \ + GTASK_INIT(&(gtask)->gt_task, TASK_NETWORK, (prio), (func), (ctx)) + +#endif /* _KERNEL */ +#endif /* _SYS_EPOCH_H_ */ diff --git a/tools/compat/include/sys/sf_buf.h b/tools/compat/include/sys/sf_buf.h index b5970d95f..b4ea671a2 100644 --- a/tools/compat/include/sys/sf_buf.h +++ b/tools/compat/include/sys/sf_buf.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2014 Gleb Smirnoff * Copyright (c) 2003-2004 Alan L. Cox * All rights reserved. @@ -41,6 +43,7 @@ struct sfstat { /* sendfile statistics */ uint64_t sf_busy; /* times aborted on a busy page */ uint64_t sf_allocfail; /* times sfbuf allocation failed */ uint64_t sf_allocwait; /* times sfbuf allocation had to wait */ + uint64_t sf_pages_bogus; /* times bogus page was used */ }; #ifdef _KERNEL @@ -74,9 +77,6 @@ struct sfstat { /* sendfile statistics */ * that do no invalidate cache on the rest of CPUs. * SFBUF_NOMD This machine doesn't have machine/sf_buf.h * - * SFBUF_OPTIONAL_DIRECT_MAP Value of this define is used as boolean - * variable that tells whether machine is - * capable of direct map or not at runtime. * SFBUF_MAP This machine provides its own sf_buf_map() and * sf_buf_unmap(). * SFBUF_PROCESS_PAGE This machine provides sf_buf_process_page() @@ -106,9 +106,6 @@ struct sf_buf; #ifndef SFBUF_NOMD #include #endif -#ifdef SFBUF_OPTIONAL_DIRECT_MAP -#include -#endif #ifdef SFBUF struct sf_buf *sf_buf_alloc(struct vm_page *, int); @@ -118,10 +115,8 @@ void sf_buf_ref(struct sf_buf *); static inline vm_offset_t sf_buf_kva(struct sf_buf *sf) { -#ifdef SFBUF_OPTIONAL_DIRECT_MAP - if (SFBUF_OPTIONAL_DIRECT_MAP) - return (SFBUF_PHYS_DMAP(VM_PAGE_TO_PHYS((vm_page_t)sf))); -#endif + if (PMAP_HAS_DMAP) + return (PHYS_TO_DMAP(VM_PAGE_TO_PHYS((vm_page_t)sf))); return (sf->kva); } @@ -129,10 +124,8 @@ sf_buf_kva(struct sf_buf *sf) static inline vm_page_t sf_buf_page(struct sf_buf *sf) { -#ifdef SFBUF_OPTIONAL_DIRECT_MAP - if (SFBUF_OPTIONAL_DIRECT_MAP) + if (PMAP_HAS_DMAP) return ((vm_page_t)sf); -#endif return (sf->m); } diff --git a/tools/compat/include/sys/socket.h b/tools/compat/include/sys/socket.h index 91c2e7fab..d2be5aad7 100644 --- a/tools/compat/include/sys/socket.h +++ b/tools/compat/include/sys/socket.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -70,7 +72,7 @@ typedef __sa_family_t sa_family_t; typedef __socklen_t socklen_t; #define _SOCKLEN_T_DECLARED #endif - + #ifndef _SSIZE_T_DECLARED typedef __ssize_t ssize_t; #define _SSIZE_T_DECLARED @@ -105,31 +107,40 @@ typedef __uint32_t uint32_t; */ #define SOCK_CLOEXEC 0x10000000 #define SOCK_NONBLOCK 0x20000000 -#endif +#ifdef _KERNEL +/* + * Flags for accept1(), kern_accept4() and solisten_dequeue, in addition + * to SOCK_CLOEXEC and SOCK_NONBLOCK. + */ +#define ACCEPT4_INHERIT 0x1 +#define ACCEPT4_COMPAT 0x2 +#endif /* _KERNEL */ +#endif /* __BSD_VISIBLE */ /* * Option flags per-socket. */ -#define SO_DEBUG 0x0001 /* turn on debugging info recording */ -#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ -#define SO_REUSEADDR 0x0004 /* allow local address reuse */ -#define SO_KEEPALIVE 0x0008 /* keep connections alive */ -#define SO_DONTROUTE 0x0010 /* just use interface addresses */ -#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */ +#define SO_DEBUG 0x00000001 /* turn on debugging info recording */ +#define SO_ACCEPTCONN 0x00000002 /* socket has had listen() */ +#define SO_REUSEADDR 0x00000004 /* allow local address reuse */ +#define SO_KEEPALIVE 0x00000008 /* keep connections alive */ +#define SO_DONTROUTE 0x00000010 /* just use interface addresses */ +#define SO_BROADCAST 0x00000020 /* permit sending of broadcast msgs */ #if __BSD_VISIBLE -#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */ +#define SO_USELOOPBACK 0x00000040 /* bypass hardware when possible */ #endif -#define SO_LINGER 0x0080 /* linger on close if data present */ -#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */ +#define SO_LINGER 0x00000080 /* linger on close if data present */ +#define SO_OOBINLINE 0x00000100 /* leave received OOB data in line */ #if __BSD_VISIBLE -#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */ -#define SO_TIMESTAMP 0x0400 /* timestamp received dgram traffic */ -#define SO_NOSIGPIPE 0x0800 /* no SIGPIPE from EPIPE */ -#define SO_ACCEPTFILTER 0x1000 /* there is an accept filter */ -#define SO_BINTIME 0x2000 /* timestamp received dgram traffic */ +#define SO_REUSEPORT 0x00000200 /* allow local address & port reuse */ +#define SO_TIMESTAMP 0x00000400 /* timestamp received dgram traffic */ +#define SO_NOSIGPIPE 0x00000800 /* no SIGPIPE from EPIPE */ +#define SO_ACCEPTFILTER 0x00001000 /* there is an accept filter */ +#define SO_BINTIME 0x00002000 /* timestamp received dgram traffic */ #endif -#define SO_NO_OFFLOAD 0x4000 /* socket cannot be offloaded */ -#define SO_NO_DDP 0x8000 /* disable direct data placement */ +#define SO_NO_OFFLOAD 0x00004000 /* socket cannot be offloaded */ +#define SO_NO_DDP 0x00008000 /* disable direct data placement */ +#define SO_REUSEPORT_LB 0x00010000 /* reuse with load balancing */ /* * Additional options, not kept in so_options. @@ -152,6 +163,18 @@ typedef __uint32_t uint32_t; #define SO_USER_COOKIE 0x1015 /* user cookie (dummynet etc.) */ #define SO_PROTOCOL 0x1016 /* get socket protocol (Linux name) */ #define SO_PROTOTYPE SO_PROTOCOL /* alias for SO_PROTOCOL (SunOS name) */ +#define SO_TS_CLOCK 0x1017 /* clock type used for SO_TIMESTAMP */ +#define SO_MAX_PACING_RATE 0x1018 /* socket's max TX pacing rate (Linux name) */ +#define SO_DOMAIN 0x1019 /* get socket domain */ +#endif + +#if __BSD_VISIBLE +#define SO_TS_REALTIME_MICRO 0 /* microsecond resolution, realtime */ +#define SO_TS_BINTIME 1 /* sub-nanosecond resolution, realtime */ +#define SO_TS_REALTIME 2 /* nanosecond resolution, realtime */ +#define SO_TS_MONOTONIC 3 /* nanosecond resolution, monotonic */ +#define SO_TS_DEFAULT SO_TS_REALTIME_MICRO +#define SO_TS_CLOCK_MAX SO_TS_MONOTONIC #endif /* @@ -236,7 +259,8 @@ struct accept_filter_arg { #define AF_IEEE80211 37 /* IEEE 802.11 protocol */ #define AF_INET_SDP 40 /* OFED Socket Direct Protocol ipv4 */ #define AF_INET6_SDP 42 /* OFED Socket Direct Protocol ipv6 */ -#define AF_MAX 42 +#define AF_HYPERV 43 /* HyperV sockets */ +#define AF_MAX 43 /* * When allocating a new AF_ constant, please only allocate * even numbered constants for FreeBSD until 134 as odd numbered AF_ @@ -244,7 +268,6 @@ struct accept_filter_arg { */ #define AF_VENDOR00 39 #define AF_VENDOR01 41 -#define AF_VENDOR02 43 #define AF_VENDOR03 45 #define AF_VENDOR04 47 #define AF_VENDOR05 49 @@ -387,6 +410,8 @@ struct sockproto { #define NET_RT_IFMALIST 4 /* return multicast address list */ #define NET_RT_IFLISTL 5 /* Survey interface list, using 'l'en * versions of msghdr structs. */ +#define NET_RT_NHOP 6 /* dump routing nexthops */ +#define NET_RT_NHGRP 7 /* dump routing nexthop groups */ #endif /* __BSD_VISIBLE */ /* @@ -408,27 +433,37 @@ struct msghdr { int msg_flags; /* flags on received message */ }; -#define MSG_OOB 0x1 /* process out-of-band data */ -#define MSG_PEEK 0x2 /* peek at incoming message */ -#define MSG_DONTROUTE 0x4 /* send without using routing tables */ -#define MSG_EOR 0x8 /* data completes record */ -#define MSG_TRUNC 0x10 /* data discarded before delivery */ -#define MSG_CTRUNC 0x20 /* control data lost before delivery */ -#define MSG_WAITALL 0x40 /* wait for full request or error */ -#if __POSIX_VISIBLE >= 200809 -#define MSG_NOSIGNAL 0x20000 /* do not generate SIGPIPE on EOF */ -#endif +#define MSG_OOB 0x00000001 /* process out-of-band data */ +#define MSG_PEEK 0x00000002 /* peek at incoming message */ +#define MSG_DONTROUTE 0x00000004 /* send without using routing tables */ +#define MSG_EOR 0x00000008 /* data completes record */ +#define MSG_TRUNC 0x00000010 /* data discarded before delivery */ +#define MSG_CTRUNC 0x00000020 /* control data lost before delivery */ +#define MSG_WAITALL 0x00000040 /* wait for full request or error */ #if __BSD_VISIBLE -#define MSG_DONTWAIT 0x80 /* this message should be nonblocking */ -#define MSG_EOF 0x100 /* data completes connection */ -#define MSG_NOTIFICATION 0x2000 /* SCTP notification */ -#define MSG_NBIO 0x4000 /* FIONBIO mode, used by fifofs */ -#define MSG_COMPAT 0x8000 /* used in sendit() */ -#define MSG_CMSG_CLOEXEC 0x40000 /* make received fds close-on-exec */ -#define MSG_WAITFORONE 0x80000 /* for recvmmsg() */ +#define MSG_DONTWAIT 0x00000080 /* this message should be nonblocking */ +#define MSG_EOF 0x00000100 /* data completes connection */ +/* 0x00000200 unused */ +/* 0x00000400 unused */ +/* 0x00000800 unused */ +/* 0x00001000 unused */ +#define MSG_NOTIFICATION 0x00002000 /* SCTP notification */ +#define MSG_NBIO 0x00004000 /* FIONBIO mode, used by fifofs */ +#define MSG_COMPAT 0x00008000 /* used in sendit() */ #endif #ifdef _KERNEL -#define MSG_SOCALLBCK 0x10000 /* for use by socket callbacks - soreceive (TCP) */ +#define MSG_SOCALLBCK 0x00010000 /* for use by socket callbacks - soreceive (TCP) */ +#endif +#if __POSIX_VISIBLE >= 200809 +#define MSG_NOSIGNAL 0x00020000 /* do not generate SIGPIPE on EOF */ +#endif +#if __BSD_VISIBLE +#define MSG_CMSG_CLOEXEC 0x00040000 /* make received fds close-on-exec */ +#define MSG_WAITFORONE 0x00080000 /* for recvmmsg() */ +#endif +#ifdef _KERNEL +#define MSG_MORETOCOME 0x00100000 /* additional data pending */ +#define MSG_TLSAPPDATA 0x00200000 /* only soreceive() app. data (TLS) */ #endif /* @@ -469,7 +504,7 @@ struct cmsgcred { }; /* - * Socket credentials. + * Socket credentials (LOCAL_CREDS). */ struct sockcred { uid_t sc_uid; /* real user id */ @@ -486,6 +521,22 @@ struct sockcred { #define SOCKCREDSIZE(ngrps) \ (sizeof(struct sockcred) + (sizeof(gid_t) * ((ngrps) - 1))) +/* + * Socket credentials (LOCAL_CREDS_PERSISTENT). + */ +struct sockcred2 { + int sc_version; /* version of this structure */ + pid_t sc_pid; /* PID of sending process */ + uid_t sc_uid; /* real user id */ + uid_t sc_euid; /* effective user id */ + gid_t sc_gid; /* real group id */ + gid_t sc_egid; /* effective group id */ + int sc_ngroups; /* number of supplemental groups */ + gid_t sc_groups[1]; /* variable length */ +}; +#define SOCKCRED2SIZE(ngrps) \ + (sizeof(struct sockcred2) + (sizeof(gid_t) * ((ngrps) - 1))) + #endif /* __BSD_VISIBLE */ /* given pointer to struct cmsghdr, return pointer to data */ @@ -527,6 +578,20 @@ struct sockcred { #define SCM_TIMESTAMP 0x02 /* timestamp (struct timeval) */ #define SCM_CREDS 0x03 /* process creds (struct cmsgcred) */ #define SCM_BINTIME 0x04 /* timestamp (struct bintime) */ +#define SCM_REALTIME 0x05 /* timestamp (struct timespec) */ +#define SCM_MONOTONIC 0x06 /* timestamp (struct timespec) */ +#define SCM_TIME_INFO 0x07 /* timestamp info */ +#define SCM_CREDS2 0x08 /* process creds (struct sockcred2) */ + +struct sock_timestamp_info { + __uint32_t st_info_flags; + __uint32_t st_info_pad0; + __uint64_t st_info_rsv[7]; +}; + +#define ST_INFO_HW 0x0001 /* SCM_TIMESTAMP was hw */ +#define ST_INFO_HW_HPREC 0x0002 /* SCM_TIMESTAMP was hw-assisted + on entrance */ #endif #if __BSD_VISIBLE @@ -566,7 +631,6 @@ struct omsghdr { #define PRU_FLUSH_RDWR SHUT_RDWR #endif - #if __BSD_VISIBLE /* * sendfile(2) header/trailer struct @@ -584,6 +648,7 @@ struct sf_hdtr { #define SF_NODISKIO 0x00000001 #define SF_MNOWAIT 0x00000002 /* obsolete */ #define SF_SYNC 0x00000004 +#define SF_USER_READAHEAD 0x00000008 #define SF_NOCACHE 0x00000010 #define SF_FLAGS(rh, flags) (((rh) << 16) | (flags)) @@ -643,5 +708,4 @@ __END_DECLS #endif /* !_KERNEL */ - #endif /* !_COMPAT_SYS_SOCKET_H_ */ diff --git a/tools/compat/include/sys/sockio.h b/tools/compat/include/sys/sockio.h index 16388d4d8..93b8af28e 100644 --- a/tools/compat/include/sys/sockio.h +++ b/tools/compat/include/sys/sockio.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -30,10 +32,10 @@ * $FreeBSD$ */ -#ifndef _COMPAT_SOCKIO_H_ -#define _COMPAT_SOCKIO_H_ +#ifndef _SYS_SOCKIO_H_ +#define _SYS_SOCKIO_H_ -#include "sys/ioccom.h" +#include /* Socket ioctl's. */ #define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */ @@ -81,6 +83,8 @@ #define SIOCSIFDESCR _IOW('i', 41, struct ifreq) /* set ifnet descr */ #define SIOCGIFDESCR _IOWR('i', 42, struct ifreq) /* get ifnet descr */ #define SIOCAIFADDR _IOW('i', 43, struct ifaliasreq)/* add/chg IF alias */ +#define SIOCGIFDATA _IOW('i', 44, struct ifreq) /* get if_data */ +#define SIOCGIFALIAS _IOWR('i', 45, struct ifaliasreq)/* get IF alias */ #define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */ #define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */ @@ -97,6 +101,7 @@ #define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */ #define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) /* set linklevel addr */ #define SIOCGI2C _IOWR('i', 61, struct ifreq) /* get I2C data */ +#define SIOCGHWADDR _IOWR('i', 62, struct ifreq) /* get hardware lladdr */ #define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif address */ #define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) /* get gif psrc addr */ @@ -133,4 +138,13 @@ #define SIOCGIFGMEMB _IOWR('i', 138, struct ifgroupreq) /* get members */ #define SIOCGIFXMEDIA _IOWR('i', 139, struct ifmediareq) /* get net xmedia */ -#endif /* !_COMPAT_SOCKIO_H_ */ +#define SIOCGIFRSSKEY _IOWR('i', 150, struct ifrsskey)/* get RSS key */ +#define SIOCGIFRSSHASH _IOWR('i', 151, struct ifrsshash)/* get the current RSS + type/func settings */ + +#define SIOCGLANPCP _IOWR('i', 152, struct ifreq) /* Get (V)LAN PCP */ +#define SIOCSLANPCP _IOW('i', 153, struct ifreq) /* Set (V)LAN PCP */ + +#define SIOCGIFDOWNREASON _IOWR('i', 154, struct ifdownreason) + +#endif /* !_SYS_SOCKIO_H_ */ diff --git a/tools/compat/include/sys/unpcb.h b/tools/compat/include/sys/unpcb.h index 41fd5745b..70cef5052 100644 --- a/tools/compat/include/sys/unpcb.h +++ b/tools/compat/include/sys/unpcb.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -33,6 +35,9 @@ #ifndef _SYS_UNPCB_H_ #define _SYS_UNPCB_H_ +typedef uint64_t unp_gen_t; + +#if defined(_KERNEL) || defined(_WANT_UNPCB) #include #include @@ -60,30 +65,39 @@ * Stream sockets keep copies of receive sockbuf sb_cc and sb_mbcnt * so that changes in the sockbuf may be computed to modify * back pressure on the sender accordingly. + * + * Locking key: + * (a) Atomic + * (c) Constant + * (g) Locked using linkage lock + * (l) Locked using list lock + * (p) Locked using pcb lock */ -typedef u_quad_t unp_gen_t; LIST_HEAD(unp_head, unpcb); struct unpcb { - LIST_ENTRY(unpcb) unp_link; /* glue on list of all PCBs */ - struct socket *unp_socket; /* pointer back to socket */ - struct file *unp_file; /* back-pointer to file for gc. */ - struct vnode *unp_vnode; /* if associated with file */ - ino_t unp_ino; /* fake inode number */ - struct unpcb *unp_conn; /* control block of connected socket */ - struct unp_head unp_refs; /* referencing socket linked list */ - LIST_ENTRY(unpcb) unp_reflink; /* link in unp_refs list */ - struct sockaddr_un *unp_addr; /* bound address of socket */ - int reserved1; - int reserved2; - unp_gen_t unp_gencnt; /* generation count of this instance */ - short unp_flags; /* flags */ - short unp_gcflag; /* Garbage collector flags. */ - struct xucred unp_peercred; /* peer credentials, if applicable */ - u_int unp_refcount; - u_int unp_msgcount; /* references from message queue */ - struct mtx unp_mtx; /* mutex */ -}; + /* Cache line 1 */ + struct mtx unp_mtx; /* PCB mutex */ + struct unpcb *unp_conn; /* (p) connected socket */ + volatile u_int unp_refcount; /* (a, p) atomic refcount */ + short unp_flags; /* (p) PCB flags */ + short unp_gcflag; /* (g) Garbage collector flags */ + struct sockaddr_un *unp_addr; /* (p) bound address of socket */ + struct socket *unp_socket; /* (c) pointer back to socket */ + /* Cache line 2 */ + u_int unp_pairbusy; /* (p) threads acquiring peer locks */ + struct vnode *unp_vnode; /* (p) associated file if applicable */ + struct xucred unp_peercred; /* (p) peer credentials if applicable */ + LIST_ENTRY(unpcb) unp_reflink; /* (l) link in unp_refs list */ + LIST_ENTRY(unpcb) unp_link; /* (g) glue on list of all PCBs */ + struct unp_head unp_refs; /* (l) referencing socket linked list */ + unp_gen_t unp_gencnt; /* (g) generation count of this item */ + struct file *unp_file; /* (g) back-pointer to file for gc */ + u_int unp_msgcount; /* (g) references from message queue */ + u_int unp_gcrefs; /* (g) garbage collector refcount */ + ino_t unp_ino; /* (g) fake inode number */ + LIST_ENTRY(unpcb) unp_dead; /* (g) link in dead list */ +} __attribute__((__aligned__(64))); /* * Flags in unp_flags. @@ -92,21 +106,13 @@ struct unpcb { * and is really the credentials of the connected peer. This is used * to determine whether the contents should be sent to the user or * not. - * - * UNP_HAVEPCCACHED - indicates that the unp_peercred member is filled - * in, but does *not* contain the credentials of the connected peer - * (there may not even be a peer). This is set in unp_listen() when - * it fills in unp_peercred for later consumption by unp_connect(). */ -#define UNP_HAVEPC 0x001 -#define UNP_HAVEPCCACHED 0x002 -#define UNP_WANTCRED 0x004 /* credentials wanted */ +#define UNP_HAVEPC 0x001 +#define UNP_WANTCRED_ALWAYS 0x002 /* credentials wanted always */ +#define UNP_WANTCRED_ONESHOT 0x004 /* credentials wanted once */ #define UNP_CONNWAIT 0x008 /* connect blocks until accepted */ -#define UNPGC_REF 0x1 /* unpcb has external ref. */ -#define UNPGC_DEAD 0x2 /* unpcb might be dead. */ -#define UNPGC_SCANNED 0x4 /* Has been scanned. */ -#define UNPGC_IGNORE_RIGHTS 0x8 /* Attached rights are freed */ +#define UNP_WANTCRED_MASK (UNP_WANTCRED_ONESHOT | UNP_WANTCRED_ALWAYS) /* * These flags are used to handle non-atomicity in connect() and bind() @@ -115,35 +121,69 @@ struct unpcb { */ #define UNP_CONNECTING 0x010 /* Currently connecting. */ #define UNP_BINDING 0x020 /* Currently binding. */ +#define UNP_WAITING 0x040 /* Peer state is changing. */ + +/* + * Flags in unp_gcflag. + */ +#define UNPGC_DEAD 0x1 /* unpcb might be dead. */ +#define UNPGC_IGNORE_RIGHTS 0x2 /* Attached rights are freed */ #define sotounpcb(so) ((struct unpcb *)((so)->so_pcb)) -/* Hack alert -- this structure depends on . */ +#endif /* _KERNEL || _WANT_UNPCB */ + +/* + * UNPCB structure exported to user-land via sysctl(3). + * + * Fields prefixed with "xu_" are unique to the export structure, and fields + * with "unp_" or other prefixes match corresponding fields of 'struct unpcb'. + * + * Legend: + * (s) - used by userland utilities in src + * (p) - used by utilities in ports + * (3) - is known to be used by third party software not in ports + * (n) - no known usage + * + * Evil hack: declare only if sys/socketvar.h have been included. + */ #ifdef _SYS_SOCKETVAR_H_ struct xunpcb { - size_t xu_len; /* length of this structure */ - struct unpcb *xu_unpp; /* to help netstat, fstat */ - struct unpcb xu_unp; /* our information */ + ksize_t xu_len; /* length of this structure */ + kvaddr_t xu_unpp; /* to help netstat, fstat */ + kvaddr_t unp_vnode; /* (s) */ + kvaddr_t unp_conn; /* (s) */ + kvaddr_t xu_firstref; /* (s) */ + kvaddr_t xu_nextref; /* (s) */ + unp_gen_t unp_gencnt; /* (s) */ + int64_t xu_spare64[8]; + int32_t xu_spare32[8]; union { - struct sockaddr_un xuu_addr; /* our bound address */ + struct sockaddr_un xu_addr; /* our bound address */ char xu_dummy1[256]; - } xu_au; -#define xu_addr xu_au.xuu_addr + }; union { - struct sockaddr_un xuu_caddr; /* their bound address */ + struct sockaddr_un xu_caddr; /* their bound address */ char xu_dummy2[256]; - } xu_cau; -#define xu_caddr xu_cau.xuu_caddr - struct xsocket xu_socket; - u_quad_t xu_alignment_hack; -}; + }; + struct xsocket xu_socket; +} __attribute__((__aligned__(MAX(8, sizeof(void *))))); struct xunpgen { - size_t xug_len; + ksize_t xug_len; u_int xug_count; unp_gen_t xug_gen; so_gen_t xug_sogen; -}; +} __attribute__((__aligned__(8))); #endif /* _SYS_SOCKETVAR_H_ */ +#if defined(_KERNEL) +struct thread; + +/* In uipc_userreq.c */ +void +unp_copy_peercred(struct thread *td, struct unpcb *client_unp, + struct unpcb *server_unp, struct unpcb *listen_unp); +#endif + #endif /* _SYS_UNPCB_H_ */ diff --git a/tools/compat/include/vm/uma.h b/tools/compat/include/vm/uma.h index 9750d54bc..f1bf7cea6 100644 --- a/tools/compat/include/vm/uma.h +++ b/tools/compat/include/vm/uma.h @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * * Copyright (c) 2002, 2003, 2004, 2005 Jeffrey Roberson * Copyright (c) 2004, 2005 Bosko Milekic * All rights reserved. @@ -36,12 +38,12 @@ #ifndef _VM_UMA_H_ #define _VM_UMA_H_ -#include #include /* For NULL */ #include /* For M_* */ +#include /* User visible parameters */ -#define UMA_SMALLEST_UNIT (PAGE_SIZE / 256) /* Smallest item allocated */ +#define UMA_SMALLEST_UNIT 8 /* Smallest item allocated */ /* Types and type defs */ @@ -49,8 +51,6 @@ struct uma_zone; /* Opaque type used as a handle to the zone */ typedef struct uma_zone * uma_zone_t; -void zone_drain(uma_zone_t); - /* * Item constructor * @@ -127,7 +127,8 @@ typedef void (*uma_fini)(void *mem, int size); /* * Import new memory into a cache zone. */ -typedef int (*uma_import)(void *arg, void **store, int count, int flags); +typedef int (*uma_import)(void *arg, void **store, int count, int domain, + int flags); /* * Free memory from a cache zone. @@ -153,7 +154,6 @@ typedef void (*uma_release)(void *arg, void **store, int count); * */ - /* Function proto types */ /* @@ -196,35 +196,23 @@ uma_zone_t uma_zcreate(const char *name, size_t size, uma_ctor ctor, * ctor/dtor/zinit/zfini may all be null, see notes above. * Note that the zinit and zfini specified here are NOT * exactly the same as the init/fini specified to uma_zcreate() - * when creating a master zone. These zinit/zfini are called + * when creating a primary zone. These zinit/zfini are called * on the TRANSITION from keg to zone (and vice-versa). Once * these are set, the primary zone may alter its init/fini * (which are called when the object passes from VM to keg) * using uma_zone_set_init/fini()) as well as its own - * zinit/zfini (unset by default for master zone) with + * zinit/zfini (unset by default for primary zone) with * uma_zone_set_zinit/zfini() (note subtle 'z' prefix). * - * master A reference to this zone's Master Zone (Primary Zone), - * which contains the backing Keg for the Secondary Zone - * being added. + * primary A reference to this zone's Primary Zone which contains the + * backing Keg for the Secondary Zone being added. * * Returns: * A pointer to a structure which is intended to be opaque to users of * the interface. The value may be null if the wait flag is not set. */ -uma_zone_t uma_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor, - uma_init zinit, uma_fini zfini, uma_zone_t master); - -/* - * Add a second master to a secondary zone. This provides multiple data - * backends for objects with the same size. Both masters must have - * compatible allocation flags. Presently, UMA_ZONE_MALLOC type zones are - * the only supported. - * - * Returns: - * Error on failure, 0 on success. - */ -int uma_zsecond_add(uma_zone_t zone, uma_zone_t master); +uma_zone_t uma_zsecond_create(const char *name, uma_ctor ctor, uma_dtor dtor, + uma_init zinit, uma_fini zfini, uma_zone_t primary); /* * Create cache-only zones. @@ -235,22 +223,22 @@ int uma_zsecond_add(uma_zone_t zone, uma_zone_t master); * zones. The 'arg' parameter is passed to import/release and is caller * specific. */ -uma_zone_t uma_zcache_create(char *name, int size, uma_ctor ctor, uma_dtor dtor, - uma_init zinit, uma_fini zfini, uma_import zimport, - uma_release zrelease, void *arg, int flags); +uma_zone_t uma_zcache_create(const char *name, int size, uma_ctor ctor, + uma_dtor dtor, uma_init zinit, uma_fini zfini, uma_import zimport, + uma_release zrelease, void *arg, int flags); /* * Definitions for uma_zcreate flags * * These flags share space with UMA_ZFLAGs in uma_int.h. Be careful not to - * overlap when adding new features. 0xf0000000 is in use by uma_int.h. + * overlap when adding new features. */ -#define UMA_ZONE_PAGEABLE 0x0001 /* Return items not fully backed by - physical memory XXX Not yet */ #define UMA_ZONE_ZINIT 0x0002 /* Initialize with zeros */ -#define UMA_ZONE_STATIC 0x0004 /* Statically sized zone */ -#define UMA_ZONE_OFFPAGE 0x0008 /* Force the slab structure allocation - off of the real memory */ +#define UMA_ZONE_CONTIG 0x0004 /* + * Physical memory underlying an object + * must be contiguous. + */ +#define UMA_ZONE_NOTOUCH 0x0008 /* UMA may not access the memory */ #define UMA_ZONE_MALLOC 0x0010 /* For use by malloc(9) only! */ #define UMA_ZONE_NOFREE 0x0020 /* Do not free slabs of this type! */ #define UMA_ZONE_MTXCLASS 0x0040 /* Create a new lock class */ @@ -258,37 +246,47 @@ uma_zone_t uma_zcache_create(char *name, int size, uma_ctor ctor, uma_dtor dtor, * Used for internal vm datastructures * only. */ -#define UMA_ZONE_HASH 0x0100 /* - * Use a hash table instead of caching - * information in the vm_page. - */ +#define UMA_ZONE_NOTPAGE 0x0100 /* allocf memory not vm pages */ #define UMA_ZONE_SECONDARY 0x0200 /* Zone is a Secondary Zone */ -/* 0x0400 Unused */ -#define UMA_ZONE_MAXBUCKET 0x0800 /* Use largest buckets */ -#define UMA_ZONE_CACHESPREAD 0x1000 /* +#define UMA_ZONE_NOBUCKET 0x0400 /* Do not use buckets. */ +#define UMA_ZONE_MAXBUCKET 0x0800 /* Use largest buckets. */ +#define UMA_ZONE_CACHESPREAD 0x2000 /* * Spread memory start locations across * all possible cache lines. May * require many virtually contiguous * backend pages and can fail early. */ -#define UMA_ZONE_VTOSLAB 0x2000 /* Zone uses vtoslab for lookup. */ #define UMA_ZONE_NODUMP 0x4000 /* * Zone's pages will not be included in * mini-dumps. */ #define UMA_ZONE_PCPU 0x8000 /* - * Allocates mp_maxid + 1 slabs sized to - * sizeof(struct pcpu). + * Allocates mp_maxid + 1 slabs of + * PAGE_SIZE */ +#define UMA_ZONE_FIRSTTOUCH 0x10000 /* First touch NUMA policy */ +#define UMA_ZONE_ROUNDROBIN 0x20000 /* Round-robin NUMA policy. */ +#define UMA_ZONE_SMR 0x40000 /* + * Safe memory reclamation defers + * frees until all read sections + * have exited. This flag creates + * a unique SMR context for this + * zone. To share contexts see + * uma_zone_set_smr() below. + * + * See sys/smr.h for more details. + */ +/* In use by UMA_ZFLAGs: 0xffe00000 */ /* - * These flags are shared between the keg and zone. In zones wishing to add - * new kegs these flags must be compatible. Some are determined based on - * physical parameters of the request and may not be provided by the consumer. + * These flags are shared between the keg and zone. Some are determined + * based on physical parameters of the request and may not be provided by + * the consumer. */ #define UMA_ZONE_INHERIT \ - (UMA_ZONE_OFFPAGE | UMA_ZONE_MALLOC | UMA_ZONE_NOFREE | \ - UMA_ZONE_HASH | UMA_ZONE_VTOSLAB | UMA_ZONE_PCPU) + (UMA_ZONE_NOTOUCH | UMA_ZONE_MALLOC | UMA_ZONE_NOFREE | \ + UMA_ZONE_VM | UMA_ZONE_NOTPAGE | UMA_ZONE_PCPU | \ + UMA_ZONE_FIRSTTOUCH | UMA_ZONE_ROUNDROBIN) /* Definitions for align */ #define UMA_ALIGN_PTR (sizeof(void *) - 1) /* Alignment fit for ptr */ @@ -297,6 +295,9 @@ uma_zone_t uma_zcache_create(char *name, int size, uma_ctor ctor, uma_dtor dtor, #define UMA_ALIGN_SHORT (sizeof(short) - 1) /* "" short */ #define UMA_ALIGN_CHAR (sizeof(char) - 1) /* "" char */ #define UMA_ALIGN_CACHE (0 - 1) /* Cache line size align */ +#define UMA_ALIGNOF(type) (_Alignof(type) - 1) /* Alignment fit for 'type' */ + +#define UMA_ANYDOMAIN -1 /* Special value for domain search. */ /* * Destroys an empty uma zone. If the zone is not empty uma complains loudly. @@ -323,6 +324,25 @@ void uma_zdestroy(uma_zone_t zone); void *uma_zalloc_arg(uma_zone_t zone, void *arg, int flags); +/* Allocate per-cpu data. Access the correct data with zpcpu_get(). */ +void *uma_zalloc_pcpu_arg(uma_zone_t zone, void *arg, int flags); + +/* Use with SMR zones. */ +void *uma_zalloc_smr(uma_zone_t zone, int flags); + +/* + * Allocate an item from a specific NUMA domain. This uses a slow path in + * the allocator but is guaranteed to allocate memory from the requested + * domain if M_WAITOK is set. + * + * Arguments: + * zone The zone we are allocating from + * arg This data is passed to the ctor function + * domain The domain to allocate from. + * flags See sys/malloc.h for available flags. + */ +void *uma_zalloc_domain(uma_zone_t zone, void *arg, int domain, int flags); + /* * Allocates an item out of a zone without supplying an argument * @@ -330,6 +350,7 @@ void *uma_zalloc_arg(uma_zone_t zone, void *arg, int flags); * */ static __inline void *uma_zalloc(uma_zone_t zone, int flags); +static __inline void *uma_zalloc_pcpu(uma_zone_t zone, int flags); static __inline void * uma_zalloc(uma_zone_t zone, int flags) @@ -337,6 +358,12 @@ uma_zalloc(uma_zone_t zone, int flags) return uma_zalloc_arg(zone, NULL, flags); } +static __inline void * +uma_zalloc_pcpu(uma_zone_t zone, int flags) +{ + return uma_zalloc_pcpu_arg(zone, NULL, flags); +} + /* * Frees an item back into the specified zone. * @@ -351,6 +378,12 @@ uma_zalloc(uma_zone_t zone, int flags) void uma_zfree_arg(uma_zone_t zone, void *item, void *arg); +/* Use with PCPU zones. */ +void uma_zfree_pcpu_arg(uma_zone_t zone, void *item, void *arg); + +/* Use with SMR zones. */ +void uma_zfree_smr(uma_zone_t zone, void *item); + /* * Frees an item back to a zone without supplying an argument * @@ -358,6 +391,7 @@ void uma_zfree_arg(uma_zone_t zone, void *item, void *arg); * */ static __inline void uma_zfree(uma_zone_t zone, void *item); +static __inline void uma_zfree_pcpu(uma_zone_t zone, void *item); static __inline void uma_zfree(uma_zone_t zone, void *item) @@ -365,10 +399,16 @@ uma_zfree(uma_zone_t zone, void *item) uma_zfree_arg(zone, item, NULL); } +static __inline void +uma_zfree_pcpu(uma_zone_t zone, void *item) +{ + uma_zfree_pcpu_arg(zone, item, NULL); +} + /* - * XXX The rest of the prototypes in this header are h0h0 magic for the VM. - * If you think you need to use it for a normal zone you're probably incorrect. + * Wait until the specified zone can allocate an item. */ +void uma_zwait(uma_zone_t zone); /* * Backend page supplier routines @@ -377,14 +417,15 @@ uma_zfree(uma_zone_t zone, void *item) * zone The zone that is requesting pages. * size The number of bytes being requested. * pflag Flags for these memory pages, see below. + * domain The NUMA domain that we prefer for this allocation. * wait Indicates our willingness to block. * * Returns: * A pointer to the allocated memory or NULL on failure. */ -typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, uint8_t *pflag, - int wait); +typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, int domain, + uint8_t *pflag, int wait); /* * Backend page free routines @@ -399,54 +440,19 @@ typedef void *(*uma_alloc)(uma_zone_t zone, vm_size_t size, uint8_t *pflag, */ typedef void (*uma_free)(void *item, vm_size_t size, uint8_t pflag); - - /* - * Sets up the uma allocator. (Called by vm_mem_init) + * Reclaims unused memory * * Arguments: - * bootmem A pointer to memory used to bootstrap the system. - * - * Returns: - * Nothing - * - * Discussion: - * This memory is used for zones which allocate things before the - * backend page supplier can give us pages. It should be - * UMA_SLAB_SIZE * boot_pages bytes. (see uma_int.h) - * - */ - -void uma_startup(void *bootmem, int boot_pages); - -/* - * Finishes starting up the allocator. This should - * be called when kva is ready for normal allocs. - * - * Arguments: - * None - * - * Returns: - * Nothing - * - * Discussion: - * uma_startup2 is called by kmeminit() to enable us of uma for malloc. - */ - -void uma_startup2(void); - -/* - * Reclaims unused memory for all zones - * - * Arguments: - * None + * req Reclamation request type. * Returns: * None - * - * This should only be called by the page out daemon. */ - -void uma_reclaim(void); +#define UMA_RECLAIM_DRAIN 1 /* release bucket cache */ +#define UMA_RECLAIM_DRAIN_CPU 2 /* release bucket and per-CPU caches */ +#define UMA_RECLAIM_TRIM 3 /* trim bucket cache to WSS */ +void uma_reclaim(int req); +void uma_zone_reclaim(uma_zone_t, int req); /* * Sets the alignment mask to be used for all zones requesting cache @@ -486,17 +492,26 @@ void uma_zone_reserve(uma_zone_t zone, int nitems); int uma_zone_reserve_kva(uma_zone_t zone, int nitems); /* - * Sets a high limit on the number of items allowed in a zone + * Sets an upper limit on the number of items allocated from a zone * * Arguments: * zone The zone to limit * nitems The requested upper limit on the number of items allowed * * Returns: - * int The effective value of nitems after rounding up based on page size + * int The effective value of nitems */ int uma_zone_set_max(uma_zone_t zone, int nitems); +/* + * Sets an upper limit on the number of items allowed in zone's caches + * + * Arguments: + * zone The zone to limit + * nitems The requested upper limit on the number of items allowed + */ +void uma_zone_set_maxcache(uma_zone_t zone, int nitems); + /* * Obtains the effective limit on the number of items in a zone * @@ -598,16 +613,24 @@ void uma_zone_set_allocf(uma_zone_t zone, uma_alloc allocf); void uma_zone_set_freef(uma_zone_t zone, uma_free freef); +/* + * Associate a zone with a smr context that is allocated after creation + * so that multiple zones may share the same context. + */ +void uma_zone_set_smr(uma_zone_t zone, smr_t smr); + +/* + * Fetch the smr context that was set or made in uma_zcreate(). + */ +smr_t uma_zone_get_smr(uma_zone_t zone); + /* * These flags are setable in the allocf and visible in the freef. */ #define UMA_SLAB_BOOT 0x01 /* Slab alloced from boot pages */ -#define UMA_SLAB_KMEM 0x02 /* Slab alloced from kmem_map */ -#define UMA_SLAB_KERNEL 0x04 /* Slab alloced from kernel_map */ +#define UMA_SLAB_KERNEL 0x04 /* Slab alloced from kmem */ #define UMA_SLAB_PRIV 0x08 /* Slab alloced from priv allocator */ -#define UMA_SLAB_OFFP 0x10 /* Slab is managed separately */ -#define UMA_SLAB_MALLOC 0x20 /* Slab is a large malloc slab */ -/* 0x40 and 0x80 are available */ +/* 0x02, 0x10, 0x40, and 0x80 are available */ /* * Used to pre-fill a zone with some number of items @@ -633,13 +656,20 @@ void uma_prealloc(uma_zone_t zone, int itemcnt); * Non-zero if zone is exhausted. */ int uma_zone_exhausted(uma_zone_t zone); -int uma_zone_exhausted_nolock(uma_zone_t zone); + +/* + * Returns the bytes of memory consumed by the zone. + */ +size_t uma_zone_memory(uma_zone_t zone); /* * Common UMA_ZONE_PCPU zones. */ +extern uma_zone_t pcpu_zone_4; +extern uma_zone_t pcpu_zone_8; +extern uma_zone_t pcpu_zone_16; +extern uma_zone_t pcpu_zone_32; extern uma_zone_t pcpu_zone_64; -extern uma_zone_t pcpu_zone_ptr; /* * Exported statistics structures to be used by user space monitoring tools. @@ -679,7 +709,8 @@ struct uma_type_header { uint64_t uth_frees; /* Zone: number of frees. */ uint64_t uth_fails; /* Zone: number of alloc failures. */ uint64_t uth_sleeps; /* Zone: number of alloc sleeps. */ - uint64_t _uth_reserved1[2]; /* Reserved. */ + uint64_t uth_xdomain; /* Zone: Number of cross domain frees. */ + uint64_t _uth_reserved1[1]; /* Reserved. */ }; struct uma_percpu_stat { @@ -692,4 +723,12 @@ struct uma_percpu_stat { void uma_reclaim_wakeup(void); void uma_reclaim_worker(void *); +unsigned long uma_limit(void); + +/* Return the amount of memory managed by UMA. */ +unsigned long uma_size(void); + +/* Return the amount of memory remaining. May be negative. */ +long uma_avail(void); + #endif /* _VM_UMA_H_ */ diff --git a/tools/compat/include/vm/uma_int.h b/tools/compat/include/vm/uma_int.h index 56cb4f6b5..e66ade02e 100644 --- a/tools/compat/include/vm/uma_int.h +++ b/tools/compat/include/vm/uma_int.h @@ -1,5 +1,7 @@ /*- - * Copyright (c) 2002-2005, 2009, 2013 Jeffrey Roberson + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2002-2019 Jeffrey Roberson * Copyright (c) 2004, 2005 Bosko Milekic * All rights reserved. * @@ -28,6 +30,9 @@ * */ +#include +#include +#include #include /* @@ -36,7 +41,22 @@ */ /* - * Here's a quick description of the relationship between the objects: + * The brief summary; Zones describe unique allocation types. Zones are + * organized into per-CPU caches which are filled by buckets. Buckets are + * organized according to memory domains. Buckets are filled from kegs which + * are also organized according to memory domains. Kegs describe a unique + * allocation type, backend memory provider, and layout. Kegs are associated + * with one or more zones and zones reference one or more kegs. Kegs provide + * slabs which are virtually contiguous collections of pages. Each slab is + * broken down int one or more items that will satisfy an individual allocation. + * + * Allocation is satisfied in the following order: + * 1) Per-CPU cache + * 2) Per-domain cache of buckets + * 3) Slab from any of N kegs + * 4) Backend page provider + * + * More detail on individual objects is contained below: * * Kegs contain lists of slabs which are stored in either the full bin, empty * bin, or partially allocated bin, to reduce fragmentation. They also contain @@ -44,6 +64,13 @@ * and rsize is the result of that. The Keg also stores information for * managing a hash of page addresses that maps pages to uma_slab_t structures * for pages that don't have embedded uma_slab_t's. + * + * Keg slab lists are organized by memory domain to support NUMA allocation + * policies. By default allocations are spread across domains to reduce the + * potential for hotspots. Special keg creation flags may be specified to + * prefer location allocation. However there is no strict enforcement as frees + * may happen on any CPU and these are returned to the CPU-local cache + * regardless of the originating domain. * * The uma_slab_t may be embedded in a UMA_SLAB_SIZE chunk of memory or it may * be allocated off the page from a special slab zone. The free list within a @@ -70,8 +97,8 @@ * safely only from their associated CPU, while the Zones backed by the same * Keg all share a common Keg lock (to coalesce contention on the backing * slabs). The backing Keg typically only serves one Zone but in the case of - * multiple Zones, one of the Zones is considered the Master Zone and all - * Zone-related stats from the Keg are done in the Master Zone. For an + * multiple Zones, one of the Zones is considered the Primary Zone and all + * Zone-related stats from the Keg are done in the Primary Zone. For an * example of a Multi-Zone setup, refer to the Mbuf allocation code. */ @@ -105,79 +132,206 @@ #ifndef VM_UMA_INT_H #define VM_UMA_INT_H -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif - #define UMA_SLAB_SIZE PAGE_SIZE /* How big are our slabs? */ #define UMA_SLAB_MASK (PAGE_SIZE - 1) /* Mask to get back to the page */ #define UMA_SLAB_SHIFT PAGE_SHIFT /* Number of bits PAGE_MASK */ -#define UMA_BOOT_PAGES 64 /* Pages allocated for startup */ -#define UMA_BOOT_PAGES_ZONES 32 /* Multiplier for pages to reserve */ - /* if uma_zone > PAGE_SIZE */ - /* Max waste percentage before going to off page slab management */ #define UMA_MAX_WASTE 10 +/* Max size of a CACHESPREAD slab. */ +#define UMA_CACHESPREAD_MAX_SIZE (128 * 1024) + /* - * I doubt there will be many cases where this is exceeded. This is the initial - * size of the hash table for uma_slabs that are managed off page. This hash - * does expand by powers of two. Currently it doesn't get smaller. + * These flags must not overlap with the UMA_ZONE flags specified in uma.h. + */ +#define UMA_ZFLAG_OFFPAGE 0x00200000 /* + * Force the slab structure + * allocation off of the real + * memory. + */ +#define UMA_ZFLAG_HASH 0x00400000 /* + * Use a hash table instead of + * caching information in the + * vm_page. + */ +#define UMA_ZFLAG_VTOSLAB 0x00800000 /* + * Zone uses vtoslab for + * lookup. + */ +#define UMA_ZFLAG_CTORDTOR 0x01000000 /* Zone has ctor/dtor set. */ +#define UMA_ZFLAG_LIMIT 0x02000000 /* Zone has limit set. */ +#define UMA_ZFLAG_CACHE 0x04000000 /* uma_zcache_create()d it */ +#define UMA_ZFLAG_RECLAIMING 0x08000000 /* Running zone_reclaim(). */ +#define UMA_ZFLAG_BUCKET 0x10000000 /* Bucket zone. */ +#define UMA_ZFLAG_INTERNAL 0x20000000 /* No offpage no PCPU. */ +#define UMA_ZFLAG_TRASH 0x40000000 /* Add trash ctor/dtor. */ + +#define UMA_ZFLAG_INHERIT \ + (UMA_ZFLAG_OFFPAGE | UMA_ZFLAG_HASH | UMA_ZFLAG_VTOSLAB | \ + UMA_ZFLAG_BUCKET | UMA_ZFLAG_INTERNAL) + +#define PRINT_UMA_ZFLAGS "\20" \ + "\37TRASH" \ + "\36INTERNAL" \ + "\35BUCKET" \ + "\34RECLAIMING" \ + "\33CACHE" \ + "\32LIMIT" \ + "\31CTORDTOR" \ + "\30VTOSLAB" \ + "\27HASH" \ + "\26OFFPAGE" \ + "\23SMR" \ + "\22ROUNDROBIN" \ + "\21FIRSTTOUCH" \ + "\20PCPU" \ + "\17NODUMP" \ + "\16CACHESPREAD" \ + "\14MAXBUCKET" \ + "\13NOBUCKET" \ + "\12SECONDARY" \ + "\11NOTPAGE" \ + "\10VM" \ + "\7MTXCLASS" \ + "\6NOFREE" \ + "\5MALLOC" \ + "\4NOTOUCH" \ + "\3CONTIG" \ + "\2ZINIT" + +/* + * Hash table for freed address -> slab translation. + * + * Only zones with memory not touchable by the allocator use the + * hash table. Otherwise slabs are found with vtoslab(). */ #define UMA_HASH_SIZE_INIT 32 -/* - * I should investigate other hashing algorithms. This should yield a low - * number of collisions if the pages are relatively contiguous. - */ - #define UMA_HASH(h, s) ((((uintptr_t)s) >> UMA_SLAB_SHIFT) & (h)->uh_hashmask) #define UMA_HASH_INSERT(h, s, mem) \ - SLIST_INSERT_HEAD(&(h)->uh_slab_hash[UMA_HASH((h), \ - (mem))], (s), us_hlink) -#define UMA_HASH_REMOVE(h, s, mem) \ - SLIST_REMOVE(&(h)->uh_slab_hash[UMA_HASH((h), \ - (mem))], (s), uma_slab, us_hlink) + LIST_INSERT_HEAD(&(h)->uh_slab_hash[UMA_HASH((h), \ + (mem))], slab_tohashslab(s), uhs_hlink) -/* Hash table for freed address -> slab translation */ +#define UMA_HASH_REMOVE(h, s) \ + LIST_REMOVE(slab_tohashslab(s), uhs_hlink) -SLIST_HEAD(slabhead, uma_slab); +LIST_HEAD(slabhashhead, uma_hash_slab); struct uma_hash { - struct slabhead *uh_slab_hash; /* Hash table for slabs */ - int uh_hashsize; /* Current size of the hash table */ - int uh_hashmask; /* Mask used during hashing */ + struct slabhashhead *uh_slab_hash; /* Hash table for slabs */ + u_int uh_hashsize; /* Current size of the hash table */ + u_int uh_hashmask; /* Mask used during hashing */ }; /* - * align field or structure to cache line + * Align field or structure to cache 'sector' in intel terminology. This + * is more efficient with adjacent line prefetch. */ -#define UMA_ALIGN __attribute__((__aligned__(64))) +#define CACHE_LINE_SHIFT 6 +#define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT) + +#if defined(__amd64__) || defined(__powerpc64__) +#define UMA_SUPER_ALIGN (CACHE_LINE_SIZE * 2) +#else +#define UMA_SUPER_ALIGN CACHE_LINE_SIZE +#endif + +#define UMA_ALIGN __attribute__((__aligned__(UMA_SUPER_ALIGN))) /* - * Structures for per cpu queues. + * The uma_bucket structure is used to queue and manage buckets divorced + * from per-cpu caches. They are loaded into uma_cache_bucket structures + * for use. */ - struct uma_bucket { - LIST_ENTRY(uma_bucket) ub_link; /* Link into the zone */ - int16_t ub_cnt; /* Count of free items. */ - int16_t ub_entries; /* Max items. */ - void *ub_bucket[]; /* actual allocation storage */ + STAILQ_ENTRY(uma_bucket) ub_link; /* Link into the zone */ + int16_t ub_cnt; /* Count of items in bucket. */ + int16_t ub_entries; /* Max items. */ + smr_seq_t ub_seq; /* SMR sequence number. */ + void *ub_bucket[]; /* actual allocation storage */ }; typedef struct uma_bucket * uma_bucket_t; +/* + * The uma_cache_bucket structure is statically allocated on each per-cpu + * cache. Its use reduces branches and cache misses in the fast path. + */ +struct uma_cache_bucket { + uma_bucket_t ucb_bucket; + int16_t ucb_cnt; + int16_t ucb_entries; + uint32_t ucb_spare; +}; + +typedef struct uma_cache_bucket * uma_cache_bucket_t; + +/* + * The uma_cache structure is allocated for each cpu for every zone + * type. This optimizes synchronization out of the allocator fast path. + */ struct uma_cache { - uma_bucket_t uc_freebucket; /* Bucket we're freeing to */ - uma_bucket_t uc_allocbucket; /* Bucket to allocate from */ - uint64_t uc_allocs; /* Count of allocations */ - uint64_t uc_frees; /* Count of frees */ + struct uma_cache_bucket uc_freebucket; /* Bucket we're freeing to */ + struct uma_cache_bucket uc_allocbucket; /* Bucket to allocate from */ + struct uma_cache_bucket uc_crossbucket; /* cross domain bucket */ + uint64_t uc_allocs; /* Count of allocations */ + uint64_t uc_frees; /* Count of frees */ } UMA_ALIGN; typedef struct uma_cache * uma_cache_t; +LIST_HEAD(slabhead, uma_slab); + +/* + * The cache structure pads perfectly into 64 bytes so we use spare + * bits from the embedded cache buckets to store information from the zone + * and keep all fast-path allocations accessing a single per-cpu line. + */ +static inline void +cache_set_uz_flags(uma_cache_t cache, uint32_t flags) +{ + + cache->uc_freebucket.ucb_spare = flags; +} + +static inline void +cache_set_uz_size(uma_cache_t cache, uint32_t size) +{ + + cache->uc_allocbucket.ucb_spare = size; +} + +static inline uint32_t +cache_uz_flags(uma_cache_t cache) +{ + + return (cache->uc_freebucket.ucb_spare); +} + +static inline uint32_t +cache_uz_size(uma_cache_t cache) +{ + + return (cache->uc_allocbucket.ucb_spare); +} + +/* + * Per-domain slab lists. Embedded in the kegs. + */ +struct uma_domain { + struct mtx_padalign ud_lock; /* Lock for the domain lists. */ + struct slabhead ud_part_slab; /* partially allocated slabs */ + struct slabhead ud_free_slab; /* completely unallocated slabs */ + struct slabhead ud_full_slab; /* fully allocated slabs */ + uint32_t ud_pages; /* Total page count */ + uint32_t ud_free_items; /* Count of items free in all slabs */ + uint32_t ud_free_slabs; /* Count of free slabs */ +} __attribute__((__aligned__(CACHE_LINE_SIZE))); + +typedef struct uma_domain * uma_domain_t; + /* * Keg management structure * @@ -185,21 +339,14 @@ typedef struct uma_cache * uma_cache_t; * */ struct uma_keg { - struct mtx_padalign uk_lock; /* Lock for the keg */ struct uma_hash uk_hash; - LIST_HEAD(,uma_zone) uk_zones; /* Keg's zones */ - LIST_HEAD(,uma_slab) uk_part_slab; /* partially allocated slabs */ - LIST_HEAD(,uma_slab) uk_free_slab; /* empty slab list */ - LIST_HEAD(,uma_slab) uk_full_slab; /* full slabs */ + struct domainset_ref uk_dr; /* Domain selection policy. */ uint32_t uk_align; /* Alignment mask */ - uint32_t uk_pages; /* Total page count */ - uint32_t uk_free; /* Count of items free in slabs */ uint32_t uk_reserve; /* Number of reserved items. */ uint32_t uk_size; /* Requested size of each item */ uint32_t uk_rsize; /* Real size of each item */ - uint32_t uk_maxpages; /* Maximum number of pages to alloc */ uma_init uk_init; /* Keg's init routine */ uma_fini uk_fini; /* Keg's fini routine */ @@ -208,10 +355,8 @@ struct uma_keg { u_long uk_offset; /* Next free offset from base KVA */ vm_offset_t uk_kva; /* Zone base KVA */ - uma_zone_t uk_slabzone; /* Slab zone backing us, if OFFPAGE */ - uint16_t uk_slabsize; /* Slab size for this keg */ - uint16_t uk_pgoff; /* Offset to uma_slab struct */ + uint32_t uk_pgoff; /* Offset to uma_slab struct */ uint16_t uk_ppera; /* pages per allocation from backend */ uint16_t uk_ipers; /* Items per slab */ uint32_t uk_flags; /* Internal flags */ @@ -219,120 +364,316 @@ struct uma_keg { /* Least used fields go to the last cache line. */ const char *uk_name; /* Name of creating zone. */ LIST_ENTRY(uma_keg) uk_link; /* List of all kegs */ + + /* Must be last, variable sized. */ + struct uma_domain uk_domain[]; /* Keg's slab lists. */ }; typedef struct uma_keg * uma_keg_t; /* * Free bits per-slab. */ -#define SLAB_SETSIZE (PAGE_SIZE / UMA_SMALLEST_UNIT) -BITSET_DEFINE(slabbits, SLAB_SETSIZE); +#define SLAB_MAX_SETSIZE (PAGE_SIZE / UMA_SMALLEST_UNIT) +#define SLAB_MIN_SETSIZE _BITSET_BITS +BITSET_DEFINE(noslabbits, 0); /* * The slab structure manages a single contiguous allocation from backing * store and subdivides it into individually allocatable items. */ struct uma_slab { - uma_keg_t us_keg; /* Keg we live in */ - union { - LIST_ENTRY(uma_slab) _us_link; /* slabs in zone */ - unsigned long _us_size; /* Size of allocation */ - } us_type; - SLIST_ENTRY(uma_slab) us_hlink; /* Link for hash table */ - uint8_t *us_data; /* First item */ - struct slabbits us_free; /* Free bitmask. */ -#ifdef INVARIANTS - struct slabbits us_debugfree; /* Debug bitmask. */ -#endif + LIST_ENTRY(uma_slab) us_link; /* slabs in zone */ uint16_t us_freecount; /* How many are free? */ uint8_t us_flags; /* Page flags see uma.h */ - uint8_t us_pad; /* Pad to 32bits, unused. */ + uint8_t us_domain; /* Backing NUMA domain. */ + struct noslabbits us_free; /* Free bitmask, flexible. */ }; -#define us_link us_type._us_link -#define us_size us_type._us_size - typedef struct uma_slab * uma_slab_t; -typedef uma_slab_t (*uma_slaballoc)(uma_zone_t, uma_keg_t, int); - -struct uma_klink { - LIST_ENTRY(uma_klink) kl_link; - uma_keg_t kl_keg; -}; -typedef struct uma_klink *uma_klink_t; /* - * Zone management structure - * - * TODO: Optimize for cache line size - * + * Slab structure with a full sized bitset and hash link for both + * HASH and OFFPAGE zones. + */ +struct uma_hash_slab { + LIST_ENTRY(uma_hash_slab) uhs_hlink; /* Link for hash table */ + uint8_t *uhs_data; /* First item */ + struct uma_slab uhs_slab; /* Must be last. */ +}; + +typedef struct uma_hash_slab * uma_hash_slab_t; + +static inline uma_hash_slab_t +slab_tohashslab(uma_slab_t slab) +{ + + return NULL; +} + +static inline void * +slab_data(uma_slab_t slab, uma_keg_t keg) +{ + + if ((keg->uk_flags & UMA_ZFLAG_OFFPAGE) == 0) + return ((void *)((uintptr_t)slab - keg->uk_pgoff)); + else + return (slab_tohashslab(slab)->uhs_data); +} + +static inline void * +slab_item(uma_slab_t slab, uma_keg_t keg, int index) +{ + uintptr_t data; + + data = (uintptr_t)slab_data(slab, keg); + return ((void *)(data + keg->uk_rsize * index)); +} + +static inline int +slab_item_index(uma_slab_t slab, uma_keg_t keg, void *item) +{ + uintptr_t data; + + data = (uintptr_t)slab_data(slab, keg); + return (((uintptr_t)item - data) / keg->uk_rsize); +} + +STAILQ_HEAD(uma_bucketlist, uma_bucket); + +struct uma_zone_domain { + struct uma_bucketlist uzd_buckets; /* full buckets */ + uma_bucket_t uzd_cross; /* Fills from cross buckets. */ + long uzd_nitems; /* total item count */ + long uzd_imax; /* maximum item count this period */ + long uzd_imin; /* minimum item count this period */ + long uzd_wss; /* working set size estimate */ + smr_seq_t uzd_seq; /* Lowest queued seq. */ + struct mtx uzd_lock; /* Lock for the domain */ +} __attribute__((__aligned__(CACHE_LINE_SIZE))); + +typedef struct uma_zone_domain * uma_zone_domain_t; + +/* + * Zone structure - per memory type. */ struct uma_zone { - struct mtx_padalign uz_lock; /* Lock for the zone */ - struct mtx_padalign *uz_lockptr; - const char *uz_name; /* Text name of the zone */ - - LIST_ENTRY(uma_zone) uz_link; /* List of all zones in keg */ - LIST_HEAD(,uma_bucket) uz_buckets; /* full buckets */ - - LIST_HEAD(,uma_klink) uz_kegs; /* List of kegs. */ - struct uma_klink uz_klink; /* klink for first keg. */ - - uma_slaballoc uz_slab; /* Allocate a slab from the backend. */ + /* Offset 0, used in alloc/free fast/medium fast path and const. */ + uint32_t uz_flags; /* Flags inherited from kegs */ + uint32_t uz_size; /* Size inherited from kegs */ uma_ctor uz_ctor; /* Constructor for each allocation */ uma_dtor uz_dtor; /* Destructor */ - uma_init uz_init; /* Initializer for each item */ - uma_fini uz_fini; /* Finalizer for each item. */ + smr_t uz_smr; /* Safe memory reclaim context. */ + uint64_t uz_max_items; /* Maximum number of items to alloc */ + uint64_t uz_bucket_max; /* Maximum bucket cache size */ + uint16_t uz_bucket_size; /* Number of items in full bucket */ + uint16_t uz_bucket_size_max; /* Maximum number of bucket items */ + uint32_t uz_sleepers; /* Threads sleeping on limit */ + counter_u64_t uz_xdomain; /* Total number of cross-domain frees */ + + /* Offset 64, used in bucket replenish. */ + uma_keg_t uz_keg; /* This zone's keg if !CACHE */ uma_import uz_import; /* Import new memory to cache. */ uma_release uz_release; /* Release memory from cache. */ void *uz_arg; /* Import/release argument. */ - - uint32_t uz_flags; /* Flags inherited from kegs */ - uint32_t uz_size; /* Size inherited from kegs */ - - volatile u_long uz_allocs UMA_ALIGN; /* Total number of allocations */ - volatile u_long uz_fails; /* Total number of alloc failures */ - volatile u_long uz_frees; /* Total number of frees */ + uma_init uz_init; /* Initializer for each item */ + uma_fini uz_fini; /* Finalizer for each item. */ + volatile uint64_t uz_items; /* Total items count & sleepers */ uint64_t uz_sleeps; /* Total number of alloc sleeps */ - uint16_t uz_count; /* Amount of items in full bucket */ - uint16_t uz_count_min; /* Minimal amount of items there */ - /* The next two fields are used to print a rate-limited warnings. */ + /* Offset 128 Rare stats, misc read-only. */ + LIST_ENTRY(uma_zone) uz_link; /* List of all zones in keg */ + counter_u64_t uz_allocs; /* Total number of allocations */ + counter_u64_t uz_frees; /* Total number of frees */ + counter_u64_t uz_fails; /* Total number of alloc failures */ + const char *uz_name; /* Text name of the zone */ + char *uz_ctlname; /* sysctl safe name string. */ + int uz_namecnt; /* duplicate name count. */ + uint16_t uz_bucket_size_min; /* Min number of items in bucket */ + uint16_t uz_pad0; + + /* Offset 192, rare read-only. */ + struct sysctl_oid *uz_oid; /* sysctl oid pointer. */ const char *uz_warning; /* Warning to print on failure */ struct timeval uz_ratecheck; /* Warnings rate-limiting */ - struct task uz_maxaction; /* Task to run when at limit */ + /* Offset 256. */ + struct mtx uz_cross_lock; /* Cross domain free lock */ + /* * This HAS to be the last item because we adjust the zone size * based on NCPU and then allocate the space for the zones. */ - struct uma_cache uz_cpu[1]; /* Per cpu caches */ + struct uma_cache uz_cpu[]; /* Per cpu caches */ + + /* domains follow here. */ }; /* - * These flags must not overlap with the UMA_ZONE flags specified in uma.h. + * Macros for interpreting the uz_items field. 20 bits of sleeper count + * and 44 bit of item count. */ -#define UMA_ZFLAG_MULTI 0x04000000 /* Multiple kegs in the zone. */ -#define UMA_ZFLAG_DRAINING 0x08000000 /* Running zone_drain. */ -#define UMA_ZFLAG_BUCKET 0x10000000 /* Bucket zone. */ -#define UMA_ZFLAG_INTERNAL 0x20000000 /* No offpage no PCPU. */ -#define UMA_ZFLAG_FULL 0x40000000 /* Reached uz_maxpages */ -#define UMA_ZFLAG_CACHEONLY 0x80000000 /* Don't ask VM for buckets. */ +#define UZ_ITEMS_SLEEPER_SHIFT 44LL +#define UZ_ITEMS_SLEEPERS_MAX ((1 << (64 - UZ_ITEMS_SLEEPER_SHIFT)) - 1) +#define UZ_ITEMS_COUNT_MASK ((1LL << UZ_ITEMS_SLEEPER_SHIFT) - 1) +#define UZ_ITEMS_COUNT(x) ((x) & UZ_ITEMS_COUNT_MASK) +#define UZ_ITEMS_SLEEPERS(x) ((x) >> UZ_ITEMS_SLEEPER_SHIFT) +#define UZ_ITEMS_SLEEPER (1LL << UZ_ITEMS_SLEEPER_SHIFT) -#define UMA_ZFLAG_INHERIT \ - (UMA_ZFLAG_INTERNAL | UMA_ZFLAG_CACHEONLY | UMA_ZFLAG_BUCKET) +#define ZONE_ASSERT_COLD(z) \ + KASSERT(uma_zone_get_allocs((z)) == 0, \ + ("zone %s initialization after use.", (z)->uz_name)) -static inline uma_keg_t -zone_first_keg(uma_zone_t zone) +/* Domains are contiguous after the last CPU */ +#define ZDOM_GET(z, n) \ + (&((uma_zone_domain_t)&(z)->uz_cpu[mp_maxid + 1])[n]) + +#undef UMA_ALIGN + +#ifdef _KERNEL +/* Internal prototypes */ +static __inline uma_slab_t hash_sfind(struct uma_hash *hash, uint8_t *data); + +/* Lock Macros */ + +#define KEG_LOCKPTR(k, d) (struct mtx *)&(k)->uk_domain[(d)].ud_lock +#define KEG_LOCK_INIT(k, d, lc) \ + do { \ + if ((lc)) \ + mtx_init(KEG_LOCKPTR(k, d), (k)->uk_name, \ + (k)->uk_name, MTX_DEF | MTX_DUPOK); \ + else \ + mtx_init(KEG_LOCKPTR(k, d), (k)->uk_name, \ + "UMA zone", MTX_DEF | MTX_DUPOK); \ + } while (0) + +#define KEG_LOCK_FINI(k, d) mtx_destroy(KEG_LOCKPTR(k, d)) +#define KEG_LOCK(k, d) \ + ({ mtx_lock(KEG_LOCKPTR(k, d)); KEG_LOCKPTR(k, d); }) +#define KEG_UNLOCK(k, d) mtx_unlock(KEG_LOCKPTR(k, d)) +#define KEG_LOCK_ASSERT(k, d) mtx_assert(KEG_LOCKPTR(k, d), MA_OWNED) + +#define KEG_GET(zone, keg) do { \ + (keg) = (zone)->uz_keg; \ + KASSERT((void *)(keg) != NULL, \ + ("%s: Invalid zone %p type", __func__, (zone))); \ + } while (0) + +#define KEG_ASSERT_COLD(k) \ + KASSERT(uma_keg_get_allocs((k)) == 0, \ + ("keg %s initialization after use.", (k)->uk_name)) + +#define ZDOM_LOCK_INIT(z, zdom, lc) \ + do { \ + if ((lc)) \ + mtx_init(&(zdom)->uzd_lock, (z)->uz_name, \ + (z)->uz_name, MTX_DEF | MTX_DUPOK); \ + else \ + mtx_init(&(zdom)->uzd_lock, (z)->uz_name, \ + "UMA zone", MTX_DEF | MTX_DUPOK); \ + } while (0) +#define ZDOM_LOCK_FINI(z) mtx_destroy(&(z)->uzd_lock) +#define ZDOM_LOCK_ASSERT(z) mtx_assert(&(z)->uzd_lock, MA_OWNED) + +#define ZDOM_LOCK(z) mtx_lock(&(z)->uzd_lock) +#define ZDOM_OWNED(z) (mtx_owner(&(z)->uzd_lock) != NULL) +#define ZDOM_UNLOCK(z) mtx_unlock(&(z)->uzd_lock) + +#define ZONE_LOCK(z) ZDOM_LOCK(ZDOM_GET((z), 0)) +#define ZONE_UNLOCK(z) ZDOM_UNLOCK(ZDOM_GET((z), 0)) + +#define ZONE_CROSS_LOCK_INIT(z) \ + mtx_init(&(z)->uz_cross_lock, "UMA Cross", NULL, MTX_DEF) +#define ZONE_CROSS_LOCK(z) mtx_lock(&(z)->uz_cross_lock) +#define ZONE_CROSS_UNLOCK(z) mtx_unlock(&(z)->uz_cross_lock) +#define ZONE_CROSS_LOCK_FINI(z) mtx_destroy(&(z)->uz_cross_lock) + +/* + * Find a slab within a hash table. This is used for OFFPAGE zones to lookup + * the slab structure. + * + * Arguments: + * hash The hash table to search. + * data The base page of the item. + * + * Returns: + * A pointer to a slab if successful, else NULL. + */ +static __inline uma_slab_t +hash_sfind(struct uma_hash *hash, uint8_t *data) { - uma_klink_t klink; + uma_hash_slab_t slab; + u_int hval; - klink = LIST_FIRST(&zone->uz_kegs); - return (klink != NULL) ? klink->kl_keg : NULL; + hval = UMA_HASH(hash, data); + + LIST_FOREACH(slab, &hash->uh_slab_hash[hval], uhs_hlink) { + if ((uint8_t *)slab->uhs_data == data) + return (&slab->uhs_slab); + } + return (NULL); } -#undef UMA_ALIGN +static __inline uma_slab_t +vtoslab(vm_offset_t va) +{ + vm_page_t p; + p = PHYS_TO_VM_PAGE(pmap_kextract(va)); + return (p->plinks.uma.slab); +} + +static __inline void +vtozoneslab(vm_offset_t va, uma_zone_t *zone, uma_slab_t *slab) +{ + vm_page_t p; + + p = PHYS_TO_VM_PAGE(pmap_kextract(va)); + *slab = p->plinks.uma.slab; + *zone = p->plinks.uma.zone; +} + +static __inline void +vsetzoneslab(vm_offset_t va, uma_zone_t zone, uma_slab_t slab) +{ + vm_page_t p; + + p = PHYS_TO_VM_PAGE(pmap_kextract(va)); + p->plinks.uma.slab = slab; + p->plinks.uma.zone = zone; +} + +extern unsigned long uma_kmem_limit; +extern unsigned long uma_kmem_total; + +/* Adjust bytes under management by UMA. */ +static inline void +uma_total_dec(unsigned long size) +{ + + atomic_subtract_long(&uma_kmem_total, size); +} + +static inline void +uma_total_inc(unsigned long size) +{ + + if (atomic_fetchadd_long(&uma_kmem_total, size) > uma_kmem_limit) + uma_reclaim_wakeup(); +} + +/* + * The following two functions may be defined by architecture specific code + * if they can provide more efficient allocation functions. This is useful + * for using direct mapped addresses. + */ +void *uma_small_alloc(uma_zone_t zone, vm_size_t bytes, int domain, + uint8_t *pflag, int wait); +void uma_small_free(void *mem, vm_size_t size, uint8_t flags); + +/* Set a global soft limit on UMA managed memory. */ +void uma_set_limit(unsigned long limit); + +#endif /* _KERNEL */ #endif /* VM_UMA_INT_H */ diff --git a/tools/ifconfig/Makefile b/tools/ifconfig/Makefile index b178dc0c7..4e5669aeb 100644 --- a/tools/ifconfig/Makefile +++ b/tools/ifconfig/Makefile @@ -1,13 +1,13 @@ # From: @(#)Makefile 8.1 (Berkeley) 6/5/93 # $FreeBSD$ -.include - -PACKAGE=runtime PROG= ifconfig SRCS= ifconfig.c # base support +TOPDIR?=${CURDIR}/../.. +include ${TOPDIR}/tools/opts.mk + # # NB: The order here defines the order in which the constructors # are called. This in turn defines the default order in which @@ -16,66 +16,78 @@ SRCS= ifconfig.c # base support # of the toolchain. # SRCS+= af_link.c # LLC support -.if ${MK_INET_SUPPORT} != "no" +ifneq (${MK_INET_SUPPORT},"no") SRCS+= af_inet.c # IPv4 support -.endif -.if ${MK_INET6_SUPPORT} != "no" +endif +ifneq (${MK_INET6_SUPPORT},"no") SRCS+= af_inet6.c # IPv6 support -.endif -.if ${MK_INET6_SUPPORT} != "no" +endif +ifneq (${MK_INET6_SUPPORT},"no") SRCS+= af_nd6.c # ND6 support -.endif +endif SRCS+= ifclone.c # clone device support + +ifneq (${MK_MAC_SUPPORT},"no") SRCS+= ifmac.c # MAC support -SRCS+= ifmedia.c # SIOC[GS]IFMEDIA support +endif + +ifneq (${MK_IFMEDIA_SUPPORT},"no") +SRCS+= ifmedia.c # SIOC[GS]IFMEDIA support +endif + SRCS+= iffib.c # non-default FIB support SRCS+= ifvlan.c # SIOC[GS]ETVLAN support SRCS+= ifvxlan.c # VXLAN support SRCS+= ifgre.c # GRE keys etc SRCS+= ifgif.c # GIF reversed header workaround + +ifneq (${MK_SFP_SUPPORT},"no") SRCS+= ifipsec.c # IPsec VTI +endif +ifneq (${MK_SFP_SUPPORT},"no") SRCS+= sfp.c # SFP/SFP+ information -LIBADD+= ifconfig m util -CFLAGS+= -I${SRCTOP}/lib/libifconfig -I${OBJTOP}/lib/libifconfig +LIBADD+= m +endif -.if ${MK_WIRELESS_SUPPORT} != "no" -SRCS+= ifieee80211.c # SIOC[GS]IEEE80211 support +ifneq (${MK_IEEE80211_SUPPORT},"no") +SRCS+= ifieee80211.c # SIOC[GS]IEEE80211 support LIBADD+= 80211 -.endif +endif SRCS+= carp.c # SIOC[GS]VH support SRCS+= ifgroup.c # ... -.if ${MK_PF} != "no" +ifneq (${MK_PF},"no") SRCS+= ifpfsync.c # pfsync(4) support -.endif +endif SRCS+= ifbridge.c # bridge support -SRCS+= iflagg.c # lagg support +ifneq (${MK_LAGG_SUPPORT},"no") +SRCS+= iflagg.c # lagg support +endif -.if ${MK_EXPERIMENTAL} != "no" +ifneq (${MK_EXPERIMENTAL},"no") CFLAGS+= -DDRAFT_IETF_6MAN_IPV6ONLY_FLAG CFLAGS+= -DEXPERIMENTAL -.endif -.if ${MK_INET6_SUPPORT} != "no" +endif +ifneq (${MK_INET6_SUPPORT},"no") CFLAGS+= -DINET6 -.endif -.if ${MK_INET_SUPPORT} != "no" +endif +ifneq (${MK_INET_SUPPORT},"no") CFLAGS+= -DINET -.endif -.if ${MK_JAIL} != "no" && !defined(RESCUE) +endif +ifneq (${MK_JAIL},"no") +ifndef (RESCUE) CFLAGS+= -DJAIL LIBADD+= jail -.endif -LIBADD+= nv +endif +endif MAN= ifconfig.8 CFLAGS+= -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings -Wnested-externs WARNS?= 2 -HAS_TESTS= -SUBDIR.${MK_TESTS}+= tests +include ${TOPDIR}/tools/prog.mk -.include diff --git a/tools/ifconfig/af_inet.c b/tools/ifconfig/af_inet.c index 3d44a4c0b..d8ff108e0 100644 --- a/tools/ifconfig/af_inet.c +++ b/tools/ifconfig/af_inet.c @@ -63,7 +63,9 @@ static void in_status(int s __unused, const struct ifaddrs *ifa) { struct sockaddr_in *sin, null_sin; +#ifndef FSTACK int error, n_flags; +#endif memset(&null_sin, 0, sizeof(null_sin)); @@ -71,6 +73,7 @@ in_status(int s __unused, const struct ifaddrs *ifa) if (sin == NULL) return; +#ifndef FSTACK if (f_addr != NULL && strcmp(f_addr, "fqdn") == 0) n_flags = 0; else if (f_addr != NULL && strcmp(f_addr, "host") == 0) @@ -82,6 +85,7 @@ in_status(int s __unused, const struct ifaddrs *ifa) sizeof(addr_buf), NULL, 0, n_flags); if (error) +#endif inet_ntop(AF_INET, &sin->sin_addr, addr_buf, sizeof(addr_buf)); printf("\tinet %s", addr_buf); @@ -134,8 +138,10 @@ static void in_getaddr(const char *s, int which) { struct sockaddr_in *sin = sintab[which]; +#ifndef FSTACK struct hostent *hp; struct netent *np; +#endif sin->sin_len = sizeof(*sin); sin->sin_family = AF_INET; @@ -166,6 +172,10 @@ in_getaddr(const char *s, int which) if (inet_aton(s, &sin->sin_addr)) return; +#ifdef FSTACK + else + errx(1, "%s: bad value", s); +#else if ((hp = gethostbyname(s)) != NULL) bcopy(hp->h_addr, (char *)&sin->sin_addr, MIN((size_t)hp->h_length, sizeof(sin->sin_addr))); @@ -173,6 +183,7 @@ in_getaddr(const char *s, int which) sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY); else errx(1, "%s: bad value", s); +#endif } static void @@ -182,6 +193,9 @@ in_status_tunnel(int s) char dst[NI_MAXHOST]; struct ifreq ifr; const struct sockaddr *sa = (const struct sockaddr *) &ifr.ifr_addr; +#ifdef FSTACK + const struct sockaddr_in *sin = (const struct sockaddr_in *)sa; +#endif memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, name, IFNAMSIZ); @@ -190,15 +204,25 @@ in_status_tunnel(int s) return; if (sa->sa_family != AF_INET) return; +#ifndef FSTACK if (getnameinfo(sa, sa->sa_len, src, sizeof(src), 0, 0, NI_NUMERICHOST) != 0) src[0] = '\0'; +#else + if (inet_ntop(AF_INET, &sin->sin_addr, src, sizeof(src)) == NULL) + return; +#endif if (ioctl(s, SIOCGIFPDSTADDR, (caddr_t)&ifr) < 0) return; if (sa->sa_family != AF_INET) return; +#ifndef FSTACK if (getnameinfo(sa, sa->sa_len, dst, sizeof(dst), 0, 0, NI_NUMERICHOST) != 0) dst[0] = '\0'; +#else + if (inet_ntop(AF_INET, &sin->sin_addr, dst, sizeof(dst)) == NULL) + return; +#endif printf("\ttunnel inet %s --> %s\n", src, dst); } @@ -233,10 +257,11 @@ static struct afswtch af_inet = { static __constructor void inet_ctor(void) { - +#ifndef FSTACK #ifndef RESCUE if (!feature_present("inet")) return; +#endif #endif af_register(&af_inet); } diff --git a/tools/ifconfig/af_inet6.c b/tools/ifconfig/af_inet6.c index 50568de4f..01f70e1e1 100644 --- a/tools/ifconfig/af_inet6.c +++ b/tools/ifconfig/af_inet6.c @@ -54,6 +54,9 @@ static const char rcsid[] = #include #include +#ifdef FSTACK +#include +#endif #include /* Define ND6_INFINITE_LIFETIME */ #include "ifconfig.h" @@ -105,7 +108,12 @@ setip6lifetime(const char *cmd, const char *val, int s, time_t newval; char *ep; - clock_gettime(CLOCK_MONOTONIC_FAST, &now); +#ifndef FSTACK + clock_gettime(CLOCK_MONOTONIC_FAST, &now); +#else + clock_gettime(CLOCK_MONOTONIC, &now); +#endif + newval = (time_t)strtoul(val, &ep, 0); if (val == ep) errx(1, "invalid %s", cmd); @@ -177,9 +185,13 @@ in6_status(int s __unused, const struct ifaddrs *ifa) u_int32_t flags6; struct in6_addrlifetime lifetime; struct timespec now; +#ifndef FSTACK int error, n_flags; clock_gettime(CLOCK_MONOTONIC_FAST, &now); +#else + clock_gettime(CLOCK_MONOTONIC, &now); +#endif memset(&null_sin, 0, sizeof(null_sin)); @@ -193,7 +205,12 @@ in6_status(int s __unused, const struct ifaddrs *ifa) return; } ifr6.ifr_addr = *sin; +#ifndef FSTACK if (ioctl(s6, SIOCGIFAFLAG_IN6, &ifr6) < 0) { +#else + if (ioctl_va(s6, SIOCGIFAFLAG_IN6, &ifr6, 1, AF_INET6) == -1) { +#endif + warn("ioctl(SIOCGIFAFLAG_IN6)"); close(s6); return; @@ -201,7 +218,11 @@ in6_status(int s __unused, const struct ifaddrs *ifa) flags6 = ifr6.ifr_ifru.ifru_flags6; memset(&lifetime, 0, sizeof(lifetime)); ifr6.ifr_addr = *sin; +#ifndef FSTACK if (ioctl(s6, SIOCGIFALIFETIME_IN6, &ifr6) < 0) { +#else + if (ioctl_va(s6, SIOCGIFALIFETIME_IN6, &ifr6, 1, AF_INET6) == -1) { +#endif warn("ioctl(SIOCGIFALIFETIME_IN6)"); close(s6); return; @@ -209,6 +230,7 @@ in6_status(int s __unused, const struct ifaddrs *ifa) lifetime = ifr6.ifr_ifru.ifru_lifetime; close(s6); +#ifndef FSTACK if (f_addr != NULL && strcmp(f_addr, "fqdn") == 0) n_flags = 0; else if (f_addr != NULL && strcmp(f_addr, "host") == 0) @@ -221,6 +243,10 @@ in6_status(int s __unused, const struct ifaddrs *ifa) if (error != 0) inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf, sizeof(addr_buf)); +#else + inet_ntop(AF_INET6_LINUX, &sin->sin6_addr, addr_buf, + sizeof(addr_buf)); +#endif printf("\tinet6 %s", addr_buf); if (ifa->ifa_flags & IFF_POINTOPOINT) { @@ -232,6 +258,7 @@ in6_status(int s __unused, const struct ifaddrs *ifa) if (sin != NULL && sin->sin6_family == AF_INET6) { int error; +#ifndef FSTACK error = getnameinfo((struct sockaddr *)sin, sin->sin6_len, addr_buf, sizeof(addr_buf), NULL, 0, @@ -239,6 +266,10 @@ in6_status(int s __unused, const struct ifaddrs *ifa) if (error != 0) inet_ntop(AF_INET6, &sin->sin6_addr, addr_buf, sizeof(addr_buf)); +#else + inet_ntop(AF_INET6_LINUX, &sin->sin6_addr, addr_buf, + sizeof(addr_buf)); +#endif printf(" --> %s", addr_buf); } } @@ -329,8 +360,10 @@ static void in6_getaddr(const char *s, int which) { struct sockaddr_in6 *sin = sin6tab[which]; +#ifndef FSTACK struct addrinfo hints, *res; int error = -1; +#endif newaddr &= 1; @@ -347,6 +380,11 @@ in6_getaddr(const char *s, int which) } } +#ifdef FSTACK + if (inet_pton(AF_INET6_LINUX, s, &sin->sin6_addr) != 1) + errx(1, "%s: bad value", s); + return; +#else if (sin->sin6_family == AF_INET6) { bzero(&hints, sizeof(struct addrinfo)); hints.ai_family = AF_INET6; @@ -359,6 +397,7 @@ in6_getaddr(const char *s, int which) freeaddrinfo(res); } } +#endif } static int @@ -437,26 +476,46 @@ in6_status_tunnel(int s) char dst[NI_MAXHOST]; struct in6_ifreq in6_ifr; const struct sockaddr *sa = (const struct sockaddr *) &in6_ifr.ifr_addr; +#ifdef FSTACK + const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa; +#endif memset(&in6_ifr, 0, sizeof(in6_ifr)); strlcpy(in6_ifr.ifr_name, name, sizeof(in6_ifr.ifr_name)); +#ifndef FSTACK if (ioctl(s, SIOCGIFPSRCADDR_IN6, (caddr_t)&in6_ifr) < 0) +#else + if (ioctl_va(s, SIOCGIFPSRCADDR_IN6, (caddr_t)&in6_ifr, 1, AF_INET6) == -1) +#endif return; if (sa->sa_family != AF_INET6) return; + +#ifndef FSTACK if (getnameinfo(sa, sa->sa_len, src, sizeof(src), 0, 0, NI_NUMERICHOST) != 0) src[0] = '\0'; if (ioctl(s, SIOCGIFPDSTADDR_IN6, (caddr_t)&in6_ifr) < 0) +#else + if (inet_ntop(AF_INET6_LINUX, &sin6->sin6_addr, src, sizeof(src)) == NULL) + return; + + if (ioctl_va(s, SIOCGIFPDSTADDR_IN6, (caddr_t)&in6_ifr, 1, AF_INET6) == -1) +#endif return; if (sa->sa_family != AF_INET6) return; + +#ifndef FSTACK if (getnameinfo(sa, sa->sa_len, dst, sizeof(dst), 0, 0, NI_NUMERICHOST) != 0) dst[0] = '\0'; - +#else + if (inet_ntop(AF_INET6_LINUX, &sin6->sin6_addr, dst, sizeof(dst)) == NULL) + return; +#endif printf("\ttunnel inet6 %s --> %s\n", src, dst); } @@ -471,7 +530,11 @@ in6_set_tunnel(int s, struct addrinfo *srcres, struct addrinfo *dstres) memcpy(&in6_addreq.ifra_dstaddr, dstres->ai_addr, dstres->ai_addr->sa_len); - if (ioctl(s, SIOCSIFPHYADDR_IN6, &in6_addreq) < 0) +#ifndef FSTACK + if (ioctl(s, SIOCSIFPHYADDR_IN6, (caddr_t)&in6_addreq) < 0) +#else + if (ioctl_va(s, SIOCSIFPHYADDR_IN6, (caddr_t)&in6_addreq, 1, AF_INET6) == -1) +#endif warn("SIOCSIFPHYADDR_IN6"); } @@ -542,12 +605,12 @@ static __constructor void inet6_ctor(void) { size_t i; - +#ifndef FSTACK #ifndef RESCUE if (!feature_present("inet6")) return; #endif - +#endif for (i = 0; i < nitems(inet6_cmds); i++) cmd_register(&inet6_cmds[i]); af_register(&af_inet6); diff --git a/tools/ifconfig/af_link.c b/tools/ifconfig/af_link.c index fb7a235b2..49988d6e3 100644 --- a/tools/ifconfig/af_link.c +++ b/tools/ifconfig/af_link.c @@ -50,6 +50,10 @@ static const char rcsid[] = #include #include +#ifdef FSTACK +#include +#endif + #include "ifconfig.h" static struct ifreq link_ridreq; @@ -148,7 +152,11 @@ link_getaddr(const char *addr, int which) sdl.sdl_alen = ETHER_ADDR_LEN; sdl.sdl_nlen = 0; sdl.sdl_family = AF_LINK; +#ifndef FSTACK arc4random_buf(&sdl.sdl_data, ETHER_ADDR_LEN); +#else + RAND_bytes((void *)&sdl.sdl_data, ETHER_ADDR_LEN); +#endif /* Non-multicast and claim it is locally administered. */ sdl.sdl_data[0] &= 0xfc; sdl.sdl_data[0] |= 0x02; diff --git a/tools/ifconfig/af_nd6.c b/tools/ifconfig/af_nd6.c index b6cda30dc..fe523e9db 100644 --- a/tools/ifconfig/af_nd6.c +++ b/tools/ifconfig/af_nd6.c @@ -52,6 +52,9 @@ static const char rcsid[] = #include #include +#ifdef FSTACK +#include +#endif #include #include "ifconfig.h" @@ -84,7 +87,11 @@ setnd6flags(const char *dummyaddr __unused, memset(&nd, 0, sizeof(nd)); strlcpy(nd.ifname, ifr.ifr_name, sizeof(nd.ifname)); +#ifndef FSTACK error = ioctl(s, SIOCGIFINFO_IN6, &nd); +#else + error = ioctl_va(s, SIOCGIFINFO_IN6, (caddr_t)&nd, 1, AF_INET6); +#endif if (error) { warn("ioctl(SIOCGIFINFO_IN6)"); return; @@ -93,7 +100,12 @@ setnd6flags(const char *dummyaddr __unused, nd.ndi.flags &= ~(-d); else nd.ndi.flags |= d; + +#ifndef FSTACK error = ioctl(s, SIOCSIFINFO_IN6, (caddr_t)&nd); +#else + error = ioctl_va(s, SIOCSIFINFO_IN6, (caddr_t)&nd, 1, AF_INET6); +#endif if (error) warn("ioctl(SIOCSIFINFO_IN6)"); } @@ -122,7 +134,11 @@ setnd6defif(const char *dummyaddr __unused, } ndifreq.ifindex = ifindex; +#ifndef FSTACK error = ioctl(s, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq); +#else + error = ioctl_va(s, SIOCSDEFIFACE_IN6, (caddr_t)&ndifreq, 1, AF_INET6); +#endif if (error) warn("ioctl(SIOCSDEFIFACE_IN6)"); } @@ -138,7 +154,11 @@ isnd6defif(int s) strlcpy(ndifreq.ifname, ifr.ifr_name, sizeof(ndifreq.ifname)); ifindex = if_nametoindex(ndifreq.ifname); +#ifndef FSTACK error = ioctl(s, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq); +#else + error = ioctl_va(s, SIOCGDEFIFACE_IN6, (caddr_t)&ndifreq, 1, AF_INET6); +#endif if (error) { warn("ioctl(SIOCGDEFIFACE_IN6)"); return (error); @@ -161,7 +181,12 @@ nd6_status(int s) warn("socket(AF_INET6, SOCK_DGRAM)"); return; } + +#ifndef FSTACK error = ioctl(s6, SIOCGIFINFO_IN6, &nd); +#else + error = ioctl_va(s, SIOCGIFINFO_IN6, (caddr_t)&nd, 1, AF_INET6); +#endif if (error) { if (errno != EPFNOSUPPORT) warn("ioctl(SIOCGIFINFO_IN6)"); diff --git a/tools/ifconfig/carp.c b/tools/ifconfig/carp.c index dcf966d87..1043fcab6 100644 --- a/tools/ifconfig/carp.c +++ b/tools/ifconfig/carp.c @@ -42,6 +42,10 @@ #include #include +#ifdef FSTACK +#include +#endif + #include #include #include @@ -77,7 +81,13 @@ carp_status(int s) carpr[0].carpr_count = CARP_MAXVHID; ifr.ifr_data = (caddr_t)&carpr; +#ifndef FSTACK if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1) +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = sizeof(struct carpreq) * CARP_MAXVHID; + if (ioctl_va(s, SIOCGVH, (caddr_t)&ifr, 3, offset, ifr.ifr_data, clen) == -1) +#endif return; for (i = 0; i < carpr[0].carpr_count; i++) { @@ -139,12 +149,24 @@ setcarp_callback(int s, void *arg __unused) carpr.carpr_count = 1; ifr.ifr_data = (caddr_t)&carpr; +#ifndef FSTACK if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1 && errno != ENOENT) +#else + size_t offset, clen; + offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + clen = sizeof(carpr); + if (ioctl_va(s, SIOCGVH, (caddr_t)&ifr, 3, offset, ifr.ifr_data, clen) == -1 + && errno != ENOENT) +#endif err(1, "SIOCGVH"); if (carpr_key != NULL) /* XXX Should hash the password into the key here? */ +#ifndef FSTACK strlcpy(carpr.carpr_key, carpr_key, CARP_KEY_LEN); +#else + strlcpy((char *)carpr.carpr_key, (const char *)carpr_key, CARP_KEY_LEN); +#endif if (carpr_advskew > -1) carpr.carpr_advskew = carpr_advskew; if (carpr_advbase > -1) @@ -152,7 +174,11 @@ setcarp_callback(int s, void *arg __unused) if (carpr_state > -1) carpr.carpr_state = carpr_state; +#ifndef FSTACK if (ioctl(s, SIOCSVH, (caddr_t)&ifr) == -1) +#else + if (ioctl_va(s, SIOCSVH, (caddr_t)&ifr, 3, offset, ifr.ifr_data, clen) == -1) +#endif err(1, "SIOCSVH"); } @@ -163,7 +189,11 @@ setcarp_passwd(const char *val, int d, int s, const struct afswtch *afp) if (carpr_vhid == -1) errx(1, "passwd requires vhid"); +#ifndef FSTACK carpr_key = val; +#else + carpr_key = (const unsigned char *)val; +#endif } static void diff --git a/tools/ifconfig/ifbridge.c b/tools/ifconfig/ifbridge.c index f4c51632b..5bbec9c7a 100644 --- a/tools/ifconfig/ifbridge.c +++ b/tools/ifconfig/ifbridge.c @@ -60,6 +60,9 @@ static const char rcsid[] = #include #include #include +#ifdef FSTACK +#include +#endif #include "ifconfig.h" @@ -94,7 +97,13 @@ do_cmd(int sock, u_long op, void *arg, size_t argsize, int set) ifd.ifd_len = argsize; ifd.ifd_data = arg; +#ifndef FSTACK return (ioctl(sock, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd)); +#else + size_t offset = (char *)&(ifd.ifd_data) - (char *)&(ifd); + return (ioctl_va(sock, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd, + 3, offset, arg, argsize)); +#endif } static void @@ -135,7 +144,11 @@ bridge_interfaces(int s, const char *prefix) } for (;;) { +#ifndef FSTACK ninbuf = realloc(inbuf, len); +#else + ninbuf = rte_malloc(NULL, len, 0); +#endif if (ninbuf == NULL) err(1, "unable to allocate interface buffer"); bifc.ifbic_len = len; @@ -181,7 +194,11 @@ bridge_interfaces(int s, const char *prefix) printf("\n"); } free(pad); +#ifndef FSTACK free(inbuf); +#else + rte_free(inbuf); +#endif } static void diff --git a/tools/ifconfig/ifclone.c b/tools/ifconfig/ifclone.c index ad39bd437..fb924bfdb 100644 --- a/tools/ifconfig/ifclone.c +++ b/tools/ifconfig/ifclone.c @@ -41,7 +41,9 @@ static const char rcsid[] = #include #include +#ifndef FSTACK #include +#endif #include #include #include @@ -57,6 +59,7 @@ typedef enum { static void list_cloners(void) { +#ifndef FSTACK ifconfig_handle_t *lifh; char *cloners; size_t cloners_count; @@ -78,6 +81,48 @@ list_cloners(void) } putchar('\n'); free(cloners); +#else + struct if_clonereq ifcr; + char *cp, *buf; + int idx; + int s; + + s = socket(AF_LOCAL, SOCK_DGRAM, 0); + if (s == -1) + err(1, "socket(AF_LOCAL,SOCK_DGRAM)"); + + memset(&ifcr, 0, sizeof(ifcr)); + + if (ioctl(s, SIOCIFGCLONERS, &ifcr) < 0) + err(1, "SIOCIFGCLONERS for count"); + + buf = malloc(ifcr.ifcr_total * IFNAMSIZ); + if (buf == NULL) + err(1, "unable to allocate cloner name buffer"); + + ifcr.ifcr_count = ifcr.ifcr_total; + ifcr.ifcr_buffer = buf; + + size_t offset = (char *)&(ifcr.ifcr_buffer) - (char *)&(ifcr); + size_t clen = ifcr.ifcr_total * IFNAMSIZ; + if (ioctl_va(s, SIOCIFGCLONERS, &ifcr, 3, offset, buf, clen) < 0) + err(1, "SIOCIFGCLONERS for names"); + + /* + * In case some disappeared in the mean time, clamp it down. + */ + if (ifcr.ifcr_count > ifcr.ifcr_total) + ifcr.ifcr_count = ifcr.ifcr_total; + + for (cp = buf, idx = 0; idx < ifcr.ifcr_count; idx++, cp += IFNAMSIZ) { + if (idx > 0) + putchar(' '); + printf("%s", cp); + } + + putchar('\n'); + free(buf); +#endif } struct clone_defcb { diff --git a/tools/ifconfig/ifconfig.c b/tools/ifconfig/ifconfig.c index e6e7908e1..b3bea7294 100644 --- a/tools/ifconfig/ifconfig.c +++ b/tools/ifconfig/ifconfig.c @@ -43,6 +43,7 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#ifndef FSTACK #include #include #include @@ -78,6 +79,36 @@ static const char rcsid[] = #include #include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "net/ethernet.h" +#include "net/if.h" +#include "net/if_dl.h" +#include "net/if_types.h" +#include "net/route.h" + +#include "sys/queue.h" +#include "sys/ioctl.h" +#include "sys/socket.h" +#include "sys/sysctl.h" + +#include "ifaddrs.h" +#include "netdb.h" + +#include "ff_ipc.h" + +#endif + #include "ifconfig.h" /* @@ -166,6 +197,19 @@ static struct module_map_entry { }, }; +#ifdef FSTACK +int +fake_socket(int domain, int type, int protocol) +{ + return 0; +} + +int +fake_close(int fd) +{ + return 0; +} +#endif void opt_register(struct option *p) @@ -188,13 +232,26 @@ usage(void) } fprintf(stderr, +#ifndef FSTACK "usage: ifconfig [-f type:format] %sinterface address_family\n" " [address [dest_address]] [parameters]\n" " ifconfig interface create\n" " ifconfig -a %s[-d] [-m] [-u] [-v] [address_family]\n" " ifconfig -l [-d] [-u] [address_family]\n" " ifconfig %s[-d] [-m] [-u] [-v]\n", +#else + "usage: ifconfig -p [-f type:format] %sinterface address_family\n" + " [address [dest_address]] [parameters]\n" + " ifconfig -p interface create\n" + " ifconfig -p -a %s[-d] [-m] [-u] [-v] [address_family]\n" + " ifconfig -p -l [-d] [-u] [address_family]\n" + " ifconfig -p %s[-d] [-m] [-u] [-v]\n", +#endif options, options, options); + +#ifdef FSTACK + ff_ipc_exit(); +#endif exit(1); } @@ -423,6 +480,10 @@ main(int argc, char *argv[]) size_t iflen; int flags; +#ifdef FSTACK + ff_ipc_init(); +#endif + all = downonly = uponly = namesonly = noload = verbose = 0; f_inet = f_inet6 = f_ether = f_addr = NULL; matchgroup = nogroup = NULL; @@ -438,11 +499,20 @@ main(int argc, char *argv[]) atexit(printifnamemaybe); /* Parse leading line options */ +#ifndef FSTACK strlcpy(options, "G:adf:klmnuv", sizeof(options)); +#else + strlcpy(options, "p:G:adf:klmnuv", sizeof(options)); +#endif for (p = opts; p != NULL; p = p->next) strlcat(options, p->opt, sizeof(options)); while ((c = getopt(argc, argv, options)) != -1) { switch (c) { +#ifdef FSTACK + case 'p': + ff_set_proc_id(atoi(optarg)); + break; +#endif case 'a': /* scan all interfaces */ all++; break; @@ -553,6 +623,9 @@ main(int argc, char *argv[]) errx(1, "%s: cloning name too long", ifname); ifconfig(argc, argv, 1, NULL); +#ifdef FSTACK + ff_ipc_exit(); +#endif exit(exit_code); } #ifdef JAIL @@ -567,6 +640,9 @@ main(int argc, char *argv[]) errx(1, "%s: interface name too long", ifname); ifconfig(argc, argv, 0, NULL); +#ifdef FSTACK + ff_ipc_exit(); +#endif exit(exit_code); } #endif @@ -698,6 +774,9 @@ main(int argc, char *argv[]) freeifaddrs(ifap); done: +#ifdef FSTACK + ff_ipc_exit(); +#endif freeformat(); exit(exit_code); } @@ -748,7 +827,13 @@ group_member(const char *ifname, const char *match, const char *nomatch) if (ifgr.ifgr_groups == NULL) errx(1, "%s: no memory", __func__); +#ifndef FSTACK if (ioctl(sock, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) +#else + size_t offset = (char *)&(ifgr.ifgr_groups) - (char *)&(ifgr); + size_t clen = len; + if (ioctl_va(sock, SIOCGIFGROUP, (caddr_t)&ifgr, 3, offset, ifgr.ifgr_groups, clen) == -1) +#endif errx(1, "%s: SIOCGIFGROUP", __func__); /* Perform matching. */ @@ -1020,7 +1105,11 @@ top: int ret; strlcpy(((struct ifreq *)afp->af_ridreq)->ifr_name, name, sizeof ifr.ifr_name); +#ifndef FSTACK ret = ioctl(s, afp->af_difaddr, afp->af_ridreq); +#else + ret = ioctl_va(s, afp->af_difaddr, afp->af_ridreq, 1, afp->af_af); +#endif if (ret < 0) { if (errno == EADDRNOTAVAIL && (doalias >= 0)) { /* means no previous address for interface */ @@ -1038,7 +1127,11 @@ top: if (newaddr && (setaddr || setmask)) { strlcpy(((struct ifreq *)afp->af_addreq)->ifr_name, name, sizeof ifr.ifr_name); +#ifndef FSTACK if (ioctl(s, afp->af_aifaddr, afp->af_addreq) < 0) +#else + if (ioctl_va(s, afp->af_aifaddr, afp->af_addreq, 1, afp->af_af) < 0) +#endif Perror("ioctl (SIOCAIFADDR)"); } @@ -1190,8 +1283,11 @@ getifflags(const char *ifname, int us) err(1, "socket(family AF_LOCAL,SOCK_DGRAM"); } else s = us; - if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) { - Perror("ioctl (SIOCGIFFLAGS)"); + if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) { + Perror("ioctl (SIOCGIFFLAGS)"); +#ifdef FSTACK + ff_ipc_exit(); +#endif exit(1); } if (us < 0) @@ -1229,10 +1325,13 @@ setifcap(const char *vname, int value, int s, const struct afswtch *afp) { int flags; - if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) < 0) { - Perror("ioctl (SIOCGIFCAP)"); - exit(1); - } + if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) < 0) { + Perror("ioctl (SIOCGIFCAP)"); +#ifdef FSTACK + ff_ipc_exit(); +#endif + exit(1); + } flags = ifr.ifr_curcap; if (value < 0) { value = -value; @@ -1303,7 +1402,13 @@ setifname(const char *val, int dummy __unused, int s, if (newname == NULL) err(1, "no memory to set ifname"); ifr.ifr_data = newname; +#ifndef FSTACK if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) { +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = strlen(newname); + if (ioctl_va(s, SIOCSIFNAME, (caddr_t)&ifr, 3, offset, newname, clen) < 0) { +#endif free(newname); err(1, "ioctl SIOCSIFNAME (set name)"); } @@ -1334,6 +1439,14 @@ setifdescr(const char *val, int dummy __unused, int s, } } +#ifdef FSTACK + if (ifr.ifr_buffer.buffer != NULL) { + size_t offset = (char *)&(ifr.ifr_buffer.buffer) - (char *)&(ifr); + if (ioctl_va(s, SIOCSIFDESCR, (caddr_t)&ifr, 3, offset, + ifr.ifr_buffer.buffer, ifr.ifr_buffer.length) < 0) + err(1, "ioctl SIOCSIFDESCR (set descr)"); + } else +#endif if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) err(1, "ioctl SIOCSIFDESCR (set descr)"); @@ -1398,7 +1511,12 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl, if ((descr = reallocf(descr, descrlen)) != NULL) { ifr.ifr_buffer.buffer = descr; ifr.ifr_buffer.length = descrlen; +#ifndef FSTACK if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) { +#else + size_t offset = (char *)&(ifr.ifr_buffer.buffer) - (char *)&(ifr); + if (ioctl_va(s, SIOCGIFDESCR, &ifr, 3, offset, descr, descrlen) == 0) { +#endif if (ifr.ifr_buffer.buffer == descr) { if (strlen(descr) > 0) printf("\tdescription: %s\n", @@ -1466,8 +1584,10 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl, if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0) printf("%s", ifs.ascii); +#ifndef FSTACK if (verbose > 0) sfp_status(s, &ifr, verbose); +#endif close(s); return; @@ -1546,6 +1666,7 @@ print_vhid(const struct ifaddrs *ifa, const char *s) void ifmaybeload(const char *name) { +#ifndef FSTACK #define MOD_PREFIX_LEN 3 /* "if_" */ struct module_stat mstat; int i, fileid, modid; @@ -1615,6 +1736,7 @@ ifmaybeload(const char *name) * infer the names of all drivers (eg mlx4en(4)). */ (void) kldload(ifkind); + #endif } static struct cmd basic_cmds[] = { diff --git a/tools/ifconfig/ifconfig.h b/tools/ifconfig/ifconfig.h index 67c25f592..d4b9e746b 100644 --- a/tools/ifconfig/ifconfig.h +++ b/tools/ifconfig/ifconfig.h @@ -38,6 +38,21 @@ #define __constructor __attribute__((constructor)) +#ifdef FSTACK +#include "compat.h" + +#ifndef __unused +#define __unused __attribute__((unused)) +#endif + +int fake_socket(int domain, int type, int protocol); +int fake_close(int fd); + +#define socket(a, b, c) fake_socket((a), (b), (c)) +#define close(a) fake_close((a)) + +#endif + struct afswtch; struct cmd; diff --git a/tools/ifconfig/ifgif.c b/tools/ifconfig/ifgif.c index b75dd4e0a..7be441688 100644 --- a/tools/ifconfig/ifgif.c +++ b/tools/ifconfig/ifgif.c @@ -63,7 +63,13 @@ gif_status(int s) int opts; ifr.ifr_data = (caddr_t)&opts; +#ifndef FSTACK if (ioctl(s, GIFGOPTS, &ifr) == -1) +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = sizeof(int); + if (ioctl_va(s, GIFGOPTS, &ifr, 3, offset, ifr.ifr_data, clen) == -1) +#endif return; if (opts == 0) return; @@ -77,7 +83,13 @@ setgifopts(const char *val, int d, int s, const struct afswtch *afp) int opts; ifr.ifr_data = (caddr_t)&opts; +#ifndef FSTACK if (ioctl(s, GIFGOPTS, &ifr) == -1) { +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = sizeof(int); + if (ioctl_va(s, GIFGOPTS, &ifr, 3, offset, ifr.ifr_data, clen) == -1) { +#endif warn("ioctl(GIFGOPTS)"); return; } @@ -87,7 +99,11 @@ setgifopts(const char *val, int d, int s, const struct afswtch *afp) else opts |= d; +#ifndef FSTACK if (ioctl(s, GIFSOPTS, &ifr) == -1) { +#else + if (ioctl_va(s, GIFSOPTS, &ifr, 3, offset, ifr.ifr_data, clen) == -1) { +#endif warn("ioctl(GIFSOPTS)"); return; } diff --git a/tools/ifconfig/ifgre.c b/tools/ifconfig/ifgre.c index d6fc0d5b5..4bd9e2474 100644 --- a/tools/ifconfig/ifgre.c +++ b/tools/ifconfig/ifgre.c @@ -26,7 +26,9 @@ */ #include +#ifndef FSTACK __FBSDID("$FreeBSD$"); +#endif #include #include @@ -55,16 +57,30 @@ gre_status(int s) opts = 0; ifr.ifr_data = (caddr_t)&opts; +#ifndef FSTACK if (ioctl(s, GREGKEY, &ifr) == 0) +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = sizeof(uint32_t); + if (ioctl_va(s, GREGKEY, &ifr, 3, offset, ifr.ifr_data, clen) == 0) +#endif if (opts != 0) printf("\tgrekey: 0x%x (%u)\n", opts, opts); opts = 0; +#ifndef FSTACK if (ioctl(s, GREGOPTS, &ifr) != 0 || opts == 0) +#else + if (ioctl_va(s, GREGOPTS, &ifr, 3, offset, ifr.ifr_data, clen) != 0 || opts == 0) +#endif return; port = 0; ifr.ifr_data = (caddr_t)&port; +#ifndef FSTACK if (ioctl(s, GREGPORT, &ifr) == 0 && port != 0) +#else + if (ioctl_va(s, GREGOPTS, &ifr, 3, offset, ifr.ifr_data, clen) != 0 || opts == 0) +#endif printf("\tudpport: %u\n", port); printb("\toptions", opts, GREBITS); putchar('\n'); @@ -78,7 +94,13 @@ setifgrekey(const char *val, int dummy __unused, int s, strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); ifr.ifr_data = (caddr_t)&grekey; +#ifndef FSTACK if (ioctl(s, GRESKEY, (caddr_t)&ifr) < 0) +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = sizeof(uint32_t); + if (ioctl_va(s, GRESKEY, (caddr_t)&ifr, 3, offset, ifr.ifr_data, clen) < 0) +#endif warn("ioctl (set grekey)"); } @@ -90,7 +112,13 @@ setifgreport(const char *val, int dummy __unused, int s, strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); ifr.ifr_data = (caddr_t)&udpport; +#ifndef FSTACK if (ioctl(s, GRESPORT, (caddr_t)&ifr) < 0) +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = sizeof(uint32_t); + if (ioctl_va(s, GRESPORT, (caddr_t)&ifr, 3, offset, ifr.ifr_data, clen) < 0) +#endif warn("ioctl (set udpport)"); } @@ -100,7 +128,13 @@ setifgreopts(const char *val, int d, int s, const struct afswtch *afp) uint32_t opts; ifr.ifr_data = (caddr_t)&opts; +#ifndef FSTACK if (ioctl(s, GREGOPTS, &ifr) == -1) { +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = sizeof(uint32_t); + if (ioctl_va(s, GREGOPTS, (caddr_t)&ifr, 3, offset, ifr.ifr_data, clen) == -1) { +#endif warn("ioctl(GREGOPTS)"); return; } @@ -110,7 +144,11 @@ setifgreopts(const char *val, int d, int s, const struct afswtch *afp) else opts |= d; +#ifndef FSTACK if (ioctl(s, GRESOPTS, &ifr) == -1) { +#else + if (ioctl_va(s, GRESOPTS, (caddr_t)&ifr, 3, offset, ifr.ifr_data, clen) == -1) { +#endif warn("ioctl(GIFSOPTS)"); return; } diff --git a/tools/ifconfig/ifgroup.c b/tools/ifconfig/ifgroup.c index 50d17ca64..0bdf93280 100644 --- a/tools/ifconfig/ifgroup.c +++ b/tools/ifconfig/ifgroup.c @@ -45,6 +45,10 @@ static const char rcsid[] = #include "ifconfig.h" +#ifdef FSTACK +#include "ff_ipc.h" +#endif + /* ARGSUSED */ static void setifgroup(const char *group_name, int d, int s, const struct afswtch *rafp) @@ -104,7 +108,13 @@ getifgroups(int s) sizeof(struct ifg_req)); if (ifgr.ifgr_groups == NULL) err(1, "getifgroups"); +#ifndef FSTACK if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) +#else + size_t offset = (char *)&(ifgr.ifgr_groups) - (char *)&(ifgr); + size_t clen = len; + if (ioctl_va(s, SIOCGIFGROUP, (caddr_t)&ifgr, 3, offset, ifgr.ifgr_groups, clen) == -1) +#endif err(1, "SIOCGIFGROUP"); cnt = 0; @@ -140,7 +150,14 @@ printgroup(const char *groupname) if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) { if (errno == EINVAL || errno == ENOTTY || errno == ENOENT) +#ifdef FSTACK + { + ff_ipc_exit(); exit(exit_code); + } +#else + exit(exit_code); +#endif else err(1, "SIOCGIFGMEMB"); } @@ -148,7 +165,14 @@ printgroup(const char *groupname) len = ifgr.ifgr_len; if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) err(1, "printgroup"); + +#ifndef FSTACK if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) +#else + size_t offset = (char *)&(ifgr.ifgr_groups) - (char *)&(ifgr); + size_t clen = len; + if (ioctl_va(s, SIOCGIFGMEMB, (caddr_t)&ifgr, 3, offset, ifgr.ifgr_groups, clen) == -1) +#endif err(1, "SIOCGIFGMEMB"); for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req); @@ -159,6 +183,9 @@ printgroup(const char *groupname) } free(ifgr.ifgr_groups); +#ifdef FSTACK + ff_ipc_exit(); +#endif exit(exit_code); } diff --git a/tools/ifconfig/ifipsec.c b/tools/ifconfig/ifipsec.c index 0e615a27e..de25e6eb9 100644 --- a/tools/ifconfig/ifipsec.c +++ b/tools/ifconfig/ifipsec.c @@ -56,7 +56,13 @@ ipsec_status(int s) uint32_t reqid; ifr.ifr_data = (caddr_t)&reqid; +#ifndef FSTACK if (ioctl(s, IPSECGREQID, &ifr) == -1) +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = sizeof(uint32_t); + if (ioctl_va(s, IPSECGREQID, &ifr, 3, offset, ifr.ifr_data, clen) == -1) +#endif return; printf("\treqid: %u\n", reqid); } @@ -74,7 +80,14 @@ DECL_CMD_FUNC(setreqid, val, arg) } strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_data = (char *)&v; +#ifndef FSTACK if (ioctl(s, IPSECSREQID, &ifr) == -1) { +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = sizeof(uint32_t); + if (ioctl_va(s, IPSECGREQID, &ifr, 3, offset, ifr.ifr_data, clen) == -1) { +#endif + warn("ioctl(IPSECSREQID)"); return; } diff --git a/tools/ifconfig/iflagg.c b/tools/ifconfig/iflagg.c index 5be8c67cd..b1d7404cc 100644 --- a/tools/ifconfig/iflagg.c +++ b/tools/ifconfig/iflagg.c @@ -279,7 +279,7 @@ lagg_status(int s) printf("\t\tactive ports: %d\n", ro.ro_active); printf("\t\tflapping: %u\n", ro.ro_flapping); if (ra.ra_proto == LAGG_PROTO_LACP) { - printf("\tlag id: %s\n", + printf("\tlagg id: %s\n", lacp_format_peer(lp, "\n\t\t ")); } } @@ -324,7 +324,13 @@ static void lagg_create(int s, struct ifreq *ifr) { ifr->ifr_data = (caddr_t) ¶ms; +#ifndef FSTACK ioctl_ifcreate(s, ifr); +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = sizeof(params); + ioctl_va(s, SIOCIFCREATE2, &ifr, 3, offset, ifr.ifr_data, clen); +#endif } static struct cmd lagg_cmds[] = { diff --git a/tools/ifconfig/ifvlan.c b/tools/ifconfig/ifvlan.c index 60f97338e..254e6be0b 100644 --- a/tools/ifconfig/ifvlan.c +++ b/tools/ifconfig/ifvlan.c @@ -81,7 +81,13 @@ getvlan(int s, struct ifreq *ifr, struct vlanreq *vreq) bzero((char *)vreq, sizeof(*vreq)); ifr->ifr_data = (caddr_t)vreq; +#ifndef FSTACK return ioctl(s, SIOCGETVLAN, (caddr_t)ifr); +#else + size_t offset = (char *)&(ifr->ifr_data) - (char *)ifr; + size_t clen = sizeof(*vreq); + return ioctl_va(s, SIOCGETVLAN, (caddr_t)ifr, 3, offset, ifr->ifr_data, clen); +#endif } static void @@ -162,6 +168,13 @@ vlan_create(int s, struct ifreq *ifr) if (params.vlr_parent[0] == '\0') errx(1, "must specify a parent device for vlan create"); ifr->ifr_data = (caddr_t) ¶ms; +#ifdef FSTACK + size_t offset = (char *)&(ifr->ifr_data) - (char *)ifr; + size_t clen = sizeof(params); + if (ioctl_va(s, SIOCIFCREATE2, ifr, 3, offset, ifr->ifr_data, clen) < 0) + err(1, "SIOCIFCREATE2"); + return; +#endif } ioctl_ifcreate(s, ifr); } @@ -178,7 +191,13 @@ vlan_set(int s, struct ifreq *ifr) { if (params.vlr_tag != NOTAG && params.vlr_parent[0] != '\0') { ifr->ifr_data = (caddr_t) ¶ms; +#ifndef FSTACK if (ioctl(s, SIOCSETVLAN, (caddr_t)ifr) == -1) +#else + size_t offset = (char *)&(ifr->ifr_data) - (char *)ifr; + size_t clen = sizeof(params); + if (ioctl_va(s, SIOCSETVLAN, ifr, 3, offset, ifr->ifr_data, clen) == -1) +#endif err(1, "SIOCSETVLAN"); } } @@ -255,13 +274,23 @@ DECL_CMD_FUNC(unsetvlandev, val, d) bzero((char *)&vreq, sizeof(struct vlanreq)); ifr.ifr_data = (caddr_t)&vreq; +#ifndef FSTACK if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) +#else + size_t offset = (char *)&(ifr.ifr_data) - (char *)&(ifr); + size_t clen = sizeof(vreq); + if (ioctl_va(s, SIOCGETVLAN, (caddr_t)&ifr, 3, offset, ifr.ifr_data, clen) == -1) +#endif err(1, "SIOCGETVLAN"); bzero((char *)&vreq.vlr_parent, sizeof(vreq.vlr_parent)); vreq.vlr_tag = 0; +#ifndef FSTACK if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) +#else + if (ioctl_va(s, SIOCSETVLAN, (caddr_t)&ifr, 3, offset, ifr.ifr_data, clen) == -1) +#endif err(1, "SIOCSETVLAN"); } diff --git a/tools/ifconfig/ifvxlan.c b/tools/ifconfig/ifvxlan.c index fda435343..ece06b6ee 100644 --- a/tools/ifconfig/ifvxlan.c +++ b/tools/ifconfig/ifvxlan.c @@ -25,7 +25,9 @@ */ #include +#ifndef FSTACK __FBSDID("$FreeBSD$"); +#endif #include #include @@ -53,6 +55,10 @@ __FBSDID("$FreeBSD$"); #include "ifconfig.h" +#ifdef FSTACK +#include "arpa/inet.h" +#endif + static struct ifvxlanparam params = { .vxlp_vni = VXLAN_VNI_MAX, }; @@ -84,7 +90,13 @@ do_cmd(int sock, u_long op, void *arg, size_t argsize, int set) ifd.ifd_len = argsize; ifd.ifd_data = arg; +#ifndef FSTACK return (ioctl(sock, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd)); +#else + size_t offset = (char *)&(ifd.ifd_data) - (char *)&(ifd); + return (ioctl_va(sock, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd, + 3, offset, ifd.ifd_data, argsize)); +#endif } static int @@ -120,12 +132,23 @@ vxlan_status(int s) if (vni >= VXLAN_VNI_MAX) return; +#ifndef FSTACK if (getnameinfo(lsa, lsa->sa_len, src, sizeof(src), srcport, sizeof(srcport), NI_NUMERICHOST | NI_NUMERICSERV) != 0) src[0] = srcport[0] = '\0'; if (getnameinfo(rsa, rsa->sa_len, dst, sizeof(dst), dstport, sizeof(dstport), NI_NUMERICHOST | NI_NUMERICSERV) != 0) dst[0] = dstport[0] = '\0'; +#else + // FIXME: ipv6 + struct sockaddr_in *sin = (struct sockaddr_in *)lsa; + if (inet_ntop(AF_INET, &sin->sin_addr, src, sizeof(src)) == NULL) + return; + + sin = (struct sockaddr_in *)rsa; + if (inet_ntop(AF_INET, &sin->sin_addr, dst, sizeof(dst)) == NULL) + return; +#endif if (!ipv6) { struct sockaddr_in *sin = (struct sockaddr_in *)rsa; @@ -191,7 +214,13 @@ vxlan_create(int s, struct ifreq *ifr) vxlan_check_params(); ifr->ifr_data = (caddr_t) ¶ms; +#ifndef FSTACK ioctl_ifcreate(s, ifr); +#else + size_t offset = (char *)&(ifr->ifr_data) - (char *)ifr; + size_t clen = sizeof(params); + ioctl_va(s, SIOCIFCREATE2, ifr, 3, offset, ifr->ifr_data, clen); +#endif } static diff --git a/tools/ipfw/Makefile b/tools/ipfw/Makefile index 552755a16..6cc42258e 100644 --- a/tools/ipfw/Makefile +++ b/tools/ipfw/Makefile @@ -1,20 +1,30 @@ # $FreeBSD$ -.include +TOPDIR?=${CURDIR}/../.. +include ${TOPDIR}/tools/opts.mk PACKAGE=ipfw PROG= ipfw -SRCS= ipfw2.c dummynet.c ipv6.c main.c nat.c tables.c +SRCS= ipfw2.c ipv6.c main.c nat.c tables.c compat.c SRCS+= nat64clat.c nat64lsn.c nat64stl.c nptv6.c -.if ${MK_PF} != "no" -SRCS+= altq.c -CFLAGS+=-DPF -.endif +ifneq (${MK_DUMMYNET},"no") +SRCS+= dummynet.c +CFLAGS+= -DDUMMYNET +endif -LIBADD= jail util +ifneq (${MK_PF},"no") +SRCS+= altq.c +CFLAGS+=-DPF +endif + +ifneq (${MK_INET6_SUPPORT},"no") +CFLAGS+= -DINET6 +endif + +LIBADD= util MAN= ipfw.8 -.include +include ${TOPDIR}/tools/prog.mk CWARNFLAGS+= -Wno-cast-align diff --git a/tools/ipfw/compat.c b/tools/ipfw/compat.c new file mode 100644 index 000000000..dcb21e4d7 --- /dev/null +++ b/tools/ipfw/compat.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ + + +#include +#include +#include + +#include "ff_ipc.h" + +static int +ipfw_ctl(int cmd, int level, int optname, void *optval, socklen_t *optlen) +{ + struct ff_msg *msg, *retmsg = NULL; + int len; + + switch (cmd) { + case FF_IPFW_GET: + if (optval == NULL || optlen == NULL) { + return EINVAL; + } + break; + case FF_IPFW_SET: + break; + default: + return EINVAL; + } + + msg = ff_ipc_msg_alloc(); + if (msg == NULL) { + errno = ENOMEM; + return -1; + } + + len = sizeof(struct ff_ipfw_args) + *optlen + sizeof(socklen_t); + if (len > msg->buf_len) { + errno = EINVAL; + ff_ipc_msg_free(msg); + return -1; + } + + msg->msg_type = FF_IPFW_CTL; + msg->ipfw.cmd = cmd; + msg->ipfw.level = level; + msg->ipfw.optname = optname; + msg->ipfw.optval = (void *)msg->buf_addr; + msg->ipfw.optlen = (socklen_t *)(msg->buf_addr + (*optlen)); + + memcpy(msg->ipfw.optval, optval, *optlen); + memcpy(msg->ipfw.optlen, optlen, sizeof(socklen_t)); + + int ret = ff_ipc_send(msg); + if (ret < 0) { + errno = EPIPE; + ff_ipc_msg_free(msg); + return -1; + } + + do { + if (retmsg != NULL) { + ff_ipc_msg_free(retmsg); + } + ret = ff_ipc_recv(&retmsg, msg->msg_type); + if (ret < 0) { + errno = EPIPE; + return -1; + } + } while (msg != retmsg); + + if (retmsg->result != 0) { + ret = -1; + errno = retmsg->result; + } else { + ret = 0; + + if (cmd == FF_IPFW_GET) { + memcpy(optval, retmsg->ipfw.optval, *(retmsg->ipfw.optlen)); + memcpy(optlen, retmsg->ipfw.optlen, sizeof(socklen_t)); + } + } + + ff_ipc_msg_free(msg); + + return ret; +} + +int +ff_socket(int domain, int type, int protocol) +{ + return 0; +} + +int ff_getsockopt(int sockfd, int level, int optname, + void *optval, socklen_t *optlen) +{ + return ipfw_ctl(FF_IPFW_GET, level, optname, optval, optlen); +} + +int ff_setsockopt(int sockfd, int level, int optname, + const void *optval, socklen_t optlen) +{ + return ipfw_ctl(FF_IPFW_SET, level, optname, (void *)optval, &optlen); +} + diff --git a/tools/ipfw/dummynet.c b/tools/ipfw/dummynet.c index 24d835fbb..e1dc1a946 100644 --- a/tools/ipfw/dummynet.c +++ b/tools/ipfw/dummynet.c @@ -404,9 +404,9 @@ print_mask(struct ipfw_flow_id *id) printf("\n mask: %sproto: 0x%02x, flow_id: 0x%08x, ", id->extra ? "queue," : "", id->proto, id->flow_id6); - inet_ntop(AF_INET6, &(id->src_ip6), buf, sizeof(buf)); + inet_ntop(AF_INET6_LINUX, &(id->src_ip6), buf, sizeof(buf)); printf("%s/0x%04x -> ", buf, id->src_port); - inet_ntop(AF_INET6, &(id->dst_ip6), buf, sizeof(buf)); + inet_ntop(AF_INET6_LINUX, &(id->dst_ip6), buf, sizeof(buf)); printf("%s/0x%04x\n", buf, id->dst_port); } } @@ -455,10 +455,10 @@ list_flow(struct buf_pr *bp, struct dn_flow *ni) else bprintf(bp, "%9u ", id->proto); bprintf(bp, "%7d %39s/%-5d ", id->flow_id6, - inet_ntop(AF_INET6, &(id->src_ip6), buff, sizeof(buff)), + inet_ntop(AF_INET6_LINUX, &(id->src_ip6), buff, sizeof(buff)), id->src_port); bprintf(bp, " %39s/%-5d ", - inet_ntop(AF_INET6, &(id->dst_ip6), buff, sizeof(buff)), + inet_ntop(AF_INET6_LINUX, &(id->dst_ip6), buff, sizeof(buff)), id->dst_port); } pr_u64(bp, &ni->tot_pkts, 4); diff --git a/tools/ipfw/ipfw2.c b/tools/ipfw/ipfw2.c index 19f7f3310..4669e593f 100644 --- a/tools/ipfw/ipfw2.c +++ b/tools/ipfw/ipfw2.c @@ -32,7 +32,9 @@ #include #include #include +#ifndef FSTACK #include +#endif #include #include #include @@ -57,6 +59,12 @@ #include #include +#ifdef FSTACK +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif +#endif + struct cmdline_opts g_co; /* global options */ struct format_opts { @@ -2310,9 +2318,9 @@ show_dyn_state(struct cmdline_opts *co, struct format_opts *fo, a.s_addr = htonl(d->id.dst_ip); bprintf(bp, " <-> %s %d", inet_ntoa(a), d->id.dst_port); } else if (d->id.addr_type == 6) { - bprintf(bp, " %s %d", inet_ntop(AF_INET6, &d->id.src_ip6, buf, + bprintf(bp, " %s %d", inet_ntop(AF_INET6_LINUX, &d->id.src_ip6, buf, sizeof(buf)), d->id.src_port); - bprintf(bp, " <-> %s %d", inet_ntop(AF_INET6, &d->id.dst_ip6, + bprintf(bp, " <-> %s %d", inet_ntop(AF_INET6_LINUX, &d->id.dst_ip6, buf, sizeof(buf)), d->id.dst_port); } else bprintf(bp, " UNKNOWN <-> UNKNOWN"); @@ -2723,7 +2731,11 @@ ipfw_list(int ac, char *av[], int show_counters) return; } if (g_co.do_pipe) { +#ifdef DUMMYNET dummynet_list(ac, av, show_counters); +#else + fprintf(stderr, "dummynet_list not supported\n"); +#endif return; } @@ -2953,9 +2965,13 @@ lookup_host (char *host, struct in_addr *ipaddr) struct hostent *he; if (!inet_aton(host, ipaddr)) { +#ifndef FSTACK if ((he = gethostbyname(host)) == NULL) return(-1); *ipaddr = *(struct in_addr *)he->h_addr_list[0]; +#else + return (-1); +#endif } return(0); } @@ -3348,7 +3364,11 @@ ipfw_delete(char *av[]) if (g_co.do_nat) { exitval = ipfw_delete_nat(i); } else if (g_co.do_pipe) { +#ifdef DUMMYNET exitval = ipfw_delete_pipe(g_co.do_pipe, i); +#else + exitval = EX_UNAVAILABLE; +#endif } else { memset(&rt, 0, sizeof(rt)); if (do_set != 0) { @@ -3727,11 +3747,11 @@ add_src(ipfw_insn *cmd, char *av, u_char proto, int cblen, struct tidx *tstate) host = av; if (proto == IPPROTO_IPV6 || strcmp(av, "me6") == 0 || - inet_pton(AF_INET6, host, &a) == 1) + inet_pton(AF_INET6_LINUX, host, &a) == 1) ret = add_srcip6(cmd, av, cblen, tstate); /* XXX: should check for IPv4, not !IPv6 */ if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 || - inet_pton(AF_INET6, host, &a) != 1)) + inet_pton(AF_INET6_LINUX, host, &a) != 1)) ret = add_srcip(cmd, av, cblen, tstate); if (ret == NULL && strcmp(av, "any") != 0) ret = cmd; @@ -3758,11 +3778,11 @@ add_dst(ipfw_insn *cmd, char *av, u_char proto, int cblen, struct tidx *tstate) host = av; if (proto == IPPROTO_IPV6 || strcmp(av, "me6") == 0 || - inet_pton(AF_INET6, host, &a) == 1) + inet_pton(AF_INET6_LINUX, host, &a) == 1) ret = add_dstip6(cmd, av, cblen, tstate); /* XXX: should check for IPv4, not !IPv6 */ if (ret == NULL && (proto == IPPROTO_IP || strcmp(av, "me") == 0 || - inet_pton(AF_INET6, host, &a) != 1)) + inet_pton(AF_INET6_LINUX, host, &a) != 1)) ret = add_dstip(cmd, av, cblen, tstate); if (ret == NULL && strcmp(av, "any") != 0) ret = cmd; @@ -4710,6 +4730,7 @@ read_options: break; case TOK_JAIL: +#ifndef FSTACK NEED1("jail requires argument"); { char *end; @@ -4737,6 +4758,9 @@ read_options: cmd->len |= F_INSN_SIZE(ipfw_insn_u32); av++; } +#else + errx(EX_USAGE, "F-Stack not support JAIL"); +#endif break; case TOK_ESTAB: @@ -5458,7 +5482,11 @@ ipfw_flush(int force) return; } if (g_co.do_pipe) { +#ifdef DUMMYNET dummynet_flush(); +#else + fprintf(stderr, "dummynet_flush not supported\n"); +#endif return; } /* `ipfw set N flush` - is the same that `ipfw delete set N` */ diff --git a/tools/ipfw/ipfw2.h b/tools/ipfw/ipfw2.h index 764e5176e..89c24de52 100644 --- a/tools/ipfw/ipfw2.h +++ b/tools/ipfw/ipfw2.h @@ -451,3 +451,15 @@ void ipfw_list_values(int ac, char *av[]); void table_fill_ntlv(struct _ipfw_obj_ntlv *ntlv, const char *name, uint8_t set, uint16_t uidx); +#ifdef FSTACK + int ff_socket(int domain, int type, int protocol); + int ff_getsockopt(int sockfd, int level, int optname, + void *optval, socklen_t *optlen); + int ff_setsockopt(int sockfd, int level, int optname, + const void *optval, socklen_t optlen); + +#define socket(a,b,c) ff_socket(a,b,c) +#define setsockopt(a,b,c,d,e) ff_setsockopt(a,b,c,d,e) +#define getsockopt(a,b,c,d,e) ff_getsockopt(a,b,c,d,e) +#endif + diff --git a/tools/ipfw/ipv6.c b/tools/ipfw/ipv6.c index eea313572..8fc780c34 100644 --- a/tools/ipfw/ipv6.c +++ b/tools/ipfw/ipv6.c @@ -42,6 +42,10 @@ #include #include +#ifdef FSTACK +#include "compat.h" +#endif + #define CHECK_LENGTH(v, len) do { \ if ((v) < (len)) \ errx(EX_DATAERR, "Rule too long"); \ @@ -114,6 +118,7 @@ print_ip6(struct buf_pr *bp, const ipfw_insn_ip6 *cmd) cmd->o.opcode == O_IP6_DST) ? 128: contigmask((const uint8_t *)&(a[1]), 128); +#ifndef FSTACK if (mb == 128 && g_co.do_resolv) he = gethostbyaddr((const char *)a, sizeof(*a), AF_INET6); @@ -121,14 +126,17 @@ print_ip6(struct buf_pr *bp, const ipfw_insn_ip6 *cmd) if (he != NULL) /* resolved to name */ bprintf(bp, "%s", he->h_name); else if (mb == 0) /* any */ +#else + if (mb == 0) /* any */ +#endif bprintf(bp, "any"); else { /* numeric IP followed by some kind of mask */ - if (inet_ntop(AF_INET6, a, trad, + if (inet_ntop(AF_INET6_LINUX, a, trad, sizeof(trad)) == NULL) bprintf(bp, "Error ntop in print_ip6\n"); bprintf(bp, "%s", trad ); if (mb < 0) /* mask not contiguous */ - bprintf(bp, "/%s", inet_ntop(AF_INET6, &a[1], + bprintf(bp, "/%s", inet_ntop(AF_INET6_LINUX, &a[1], trad, sizeof(trad))); else if (mb < 128) bprintf(bp, "/%d", mb); @@ -302,8 +310,10 @@ lookup_host6 (char *host, struct in6_addr *ip6addr) { struct hostent *he; - if (!inet_pton(AF_INET6, host, ip6addr)) { + if (!inet_pton(AF_INET6_LINUX, host, ip6addr)) { +#ifndef FSTACK if ((he = gethostbyname2(host, AF_INET6)) == NULL) +#endif return(-1); memcpy(ip6addr, he->h_addr_list[0], sizeof( struct in6_addr)); } @@ -387,7 +397,7 @@ fill_ip6(ipfw_insn_ip6 *cmd, char *av, int cblen, struct tidx *tstate) } /* next, look at the mask, if any */ if (md == '/' && strchr(p, ':')) { - if (!inet_pton(AF_INET6, p, &d[1])) + if (!inet_pton(AF_INET6_LINUX, p, &d[1])) errx(EX_DATAERR, "bad mask \"%s\"", p); masklen = contigmask((uint8_t *)&(d[1]), 128); diff --git a/tools/ipfw/main.c b/tools/ipfw/main.c index dc55d0bfa..6d4759983 100644 --- a/tools/ipfw/main.c +++ b/tools/ipfw/main.c @@ -31,6 +31,13 @@ #include #include +#ifdef FSTACK +#include +#include "compat.h" + +#include "ff_ipc.h" +#endif + #include "ipfw2.h" static void @@ -38,7 +45,11 @@ help(void) { fprintf(stderr, "ipfw syntax summary (but please do read the ipfw(8) manpage):\n\n" +#ifndef FSTACK "\tipfw [-abcdefhnNqStTv] \n\n" +#else +"\tipfw -P [-abcdefhnNqStTv] \n\n" +#endif "where is one of the following:\n\n" "add [num] [set N] [prob x] RULE-BODY\n" "{pipe|queue} N config PIPE-BODY\n" @@ -76,6 +87,10 @@ help(void) " tcpdatalen LIST | verrevpath | versrcreach | antispoof\n" ); +#ifdef FSTACK + ff_ipc_exit(); +#endif + exit(0); } @@ -262,7 +277,11 @@ ipfw_main(int oldac, char **oldav) save_av = av; optind = optreset = 1; /* restart getopt() */ +#ifndef FSTACK while ((ch = getopt(ac, av, "abcdDefhinNp:qs:STtv")) != -1) +#else + while ((ch = getopt(ac, av, "abcdDefhinNp:qs:STtvP:")) != -1) +#endif switch (ch) { case 'a': do_acct = 1; @@ -339,6 +358,12 @@ ipfw_main(int oldac, char **oldav) g_co.verbose = 1; break; +#ifdef FSTACK + case 'P': + ff_set_proc_id(atoi(optarg)); + break; +#endif + default: free(save_av); return 1; @@ -411,7 +436,13 @@ ipfw_main(int oldac, char **oldav) else if (g_co.do_nat && _substrcmp(*av, "show") == 0) ipfw_show_nat(ac, av); else if (g_co.do_pipe && _substrcmp(*av, "config") == 0) - ipfw_config_pipe(ac, av); +#ifdef DUMMYNET + ipfw_config_pipe(ac, av); +#else + { + errx(EX_UNAVAILABLE, "ipfw_config_pipe not supported"); + } +#endif else if (g_co.do_nat && _substrcmp(*av, "config") == 0) ipfw_config_nat(ac, av); else if (_substrcmp(*av, "set") == 0) @@ -474,7 +505,11 @@ ipfw_readfile(int ac, char *av[]) FILE *f = NULL; pid_t preproc = 0; +#ifndef FSTACK while ((c = getopt(ac, av, "cfNnp:qS")) != -1) { +#else + while ((c = getopt(ac, av, "cfNnp:qSP:")) != -1) { +#endif switch(c) { case 'c': g_co.do_compact = 1; @@ -525,6 +560,12 @@ ipfw_readfile(int ac, char *av[]) g_co.show_sets = 1; break; +#ifdef FSTACK + case 'P': + ff_set_proc_id(atoi(optarg)); + break; +#endif + default: errx(EX_USAGE, "bad arguments, for usage" " summary ``ipfw''"); @@ -580,7 +621,9 @@ ipfw_readfile(int ac, char *av[]) lineno++; snprintf(linename, sizeof(linename), "Line %d", lineno); +#ifndef FSTACK setprogname(linename); /* XXX */ +#endif args[0] = progname; args[1] = buf; ipfw_main(2, args); @@ -623,7 +666,9 @@ main(int ac, char *av[]) * If the last argument is an absolute pathname, interpret it * as a file to be preprocessed. */ - +#ifdef FSTACK + ff_ipc_init(); +#endif if (ac > 1 && av[ac - 1][0] == '/') { if (access(av[ac - 1], R_OK) == 0) ipfw_readfile(ac, av); @@ -636,5 +681,8 @@ main(int ac, char *av[]) "do \"ipfw -h\" or \"man ipfw\" for details"); } } +#ifdef FSTACK + ff_ipc_exit(); +#endif return EX_OK; } diff --git a/tools/ipfw/nat.c b/tools/ipfw/nat.c index bbf5be666..4bf19decf 100644 --- a/tools/ipfw/nat.c +++ b/tools/ipfw/nat.c @@ -45,6 +45,12 @@ #include #include +#ifdef FSTACK +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif +#endif + typedef int (nat_cb_t)(struct nat44_cfg_nat *cfg, void *arg); static void nat_show_cfg(struct nat44_cfg_nat *n, void *arg); static void nat_show_log(struct nat44_cfg_nat *n, void *arg); @@ -204,12 +210,17 @@ StrToAddr (const char* str, struct in_addr* addr) if (inet_aton (str, addr)) return; +#ifdef FSTACK + else + errx (1, "invalid addr %d", addr->s_addr); +#else hp = gethostbyname (str); if (!hp) errx (1, "unknown host %s", str); memcpy (addr, hp->h_addr, sizeof (struct in_addr)); +#endif } static int diff --git a/tools/ipfw/nat64clat.c b/tools/ipfw/nat64clat.c index 962fe7064..22ab31940 100644 --- a/tools/ipfw/nat64clat.c +++ b/tools/ipfw/nat64clat.c @@ -51,6 +51,12 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef FSTACK +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif +#endif + typedef int (nat64clat_cb_t)(ipfw_nat64clat_cfg *i, const char *name, uint8_t set); static int nat64clat_foreach(nat64clat_cb_t *f, const char *name, uint8_t set, diff --git a/tools/ipfw/nat64lsn.c b/tools/ipfw/nat64lsn.c index ff3618181..72ed42340 100644 --- a/tools/ipfw/nat64lsn.c +++ b/tools/ipfw/nat64lsn.c @@ -51,6 +51,12 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef FSTACK +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif +#endif + static void nat64lsn_fill_ntlv(ipfw_obj_ntlv *ntlv, const char *name, uint8_t set); typedef int (nat64lsn_cb_t)(ipfw_nat64lsn_cfg *cfg, const char *name, diff --git a/tools/ipfw/nat64stl.c b/tools/ipfw/nat64stl.c index e82ec202b..f032f7c4b 100644 --- a/tools/ipfw/nat64stl.c +++ b/tools/ipfw/nat64stl.c @@ -50,6 +50,12 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef FSTACK +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif +#endif + typedef int (nat64stl_cb_t)(ipfw_nat64stl_cfg *i, const char *name, uint8_t set); static int nat64stl_foreach(nat64stl_cb_t *f, const char *name, uint8_t set, diff --git a/tools/ipfw/nptv6.c b/tools/ipfw/nptv6.c index f2ebbdb65..2e027295b 100644 --- a/tools/ipfw/nptv6.c +++ b/tools/ipfw/nptv6.c @@ -48,6 +48,11 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef FSTACK +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif +#endif typedef int (nptv6_cb_t)(ipfw_nptv6_cfg *i, const char *name, uint8_t set); static int nptv6_foreach(nptv6_cb_t *f, const char *name, uint8_t set, diff --git a/tools/ipfw/tables.c b/tools/ipfw/tables.c index 57b8cef00..be4637844 100644 --- a/tools/ipfw/tables.c +++ b/tools/ipfw/tables.c @@ -39,6 +39,12 @@ #include "ipfw2.h" +#ifdef FSTACK +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif +#endif + static void table_modify_record(ipfw_obj_header *oh, int ac, char *av[], int add, int quiet, int update, int atomic); static int table_flush(ipfw_obj_header *oh); @@ -122,9 +128,13 @@ lookup_host (char *host, struct in_addr *ipaddr) struct hostent *he; if (!inet_aton(host, ipaddr)) { +#ifndef FSTACK if ((he = gethostbyname(host)) == NULL) return(-1); *ipaddr = *(struct in_addr *)he->h_addr_list[0]; +#else + return (-1); +#endif } return(0); } @@ -1198,7 +1208,7 @@ tentry_fill_key_type(char *arg, ipfw_obj_tentry *tentry, uint8_t type, masklen = p ? mask : 32; af = AF_INET; - } else if (inet_pton(AF_INET6, arg, paddr) == 1) { + } else if (inet_pton(AF_INET6_LINUX, arg, paddr) == 1) { if (IN6_IS_ADDR_V4COMPAT(paddr)) errx(EX_DATAERR, "Use IPv4 instead of v4-compatible"); @@ -1251,7 +1261,7 @@ tentry_fill_key_type(char *arg, ipfw_obj_tentry *tentry, uint8_t type, "Inconsistent address family\n"); af = AF_INET; memcpy(&tfe->a.a4.sip, &tmp, 4); - } else if (inet_pton(AF_INET6, arg, &tmp) == 1) { + } else if (inet_pton(AF_INET6_LINUX, arg, &tmp) == 1) { if (af != 0 && af != AF_INET6) errx(EX_DATAERR, "Inconsistent address family\n"); @@ -1317,7 +1327,7 @@ tentry_fill_key_type(char *arg, ipfw_obj_tentry *tentry, uint8_t type, "Inconsistent address family"); af = AF_INET; memcpy(&tfe->a.a4.dip, &tmp, 4); - } else if (inet_pton(AF_INET6, arg, &tmp) == 1) { + } else if (inet_pton(AF_INET6_LINUX, arg, &tmp) == 1) { if (af != 0 && af != AF_INET6) errx(EX_DATAERR, "Inconsistent address family"); @@ -1378,7 +1388,7 @@ guess_key_type(char *key, uint8_t *ptype) *p = '\0'; if ((inet_pton(AF_INET, key, &addr) == 1) || - (inet_pton(AF_INET6, key, &addr) == 1)) { + (inet_pton(AF_INET6_LINUX, key, &addr) == 1)) { *ptype = IPFW_TABLE_CIDR; if (p != NULL) *p = '/'; @@ -1614,6 +1624,7 @@ tentry_fill_value(ipfw_obj_header *oh __unused, ipfw_obj_tentry *tent, memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_flags = AI_NUMERICHOST; + /* FIXME: getaddrinfo not support IPv6 */ if (getaddrinfo(n, NULL, &hints, &res) == 0) { v->nh6 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; @@ -1836,9 +1847,13 @@ table_show_value(char *buf, size_t bufsize, ipfw_table_value *v, sa6.sin6_addr = v->nh6; sa6.sin6_port = 0; sa6.sin6_scope_id = v->zoneid; +#ifndef FSTACK if (getnameinfo((const struct sockaddr *)&sa6, sa6.sin6_len, abuf, sizeof(abuf), NULL, 0, NI_NUMERICHOST) == 0) +#else + if (inet_ntop(AF_INET6_LINUX, &sa6.sin6_addr, abuf, sizeof(abuf)) != NULL) +#endif l = snprintf(buf, sz, "%s,", abuf); break; } diff --git a/tools/libmemstat/Makefile b/tools/libmemstat/Makefile index 597dc6db1..55bdd4f09 100644 --- a/tools/libmemstat/Makefile +++ b/tools/libmemstat/Makefile @@ -1,5 +1,8 @@ # $FreeBSD$ +TOPDIR?=${CURDIR}/../.. +include ${TOPDIR}/tools/opts.mk + WARNS?= 3 LIB= memstat SHLIB_MAJOR= 3 @@ -26,4 +29,4 @@ MLINKS+= libmemstat.3 memstat_kvm_all.3 MLINKS+= libmemstat.3 memstat_kvm_malloc.3 MLINKS+= libmemstat.3 memstat_kvm_uma.3 -.include +include ${TOPDIR}/tools/lib.mk diff --git a/tools/libmemstat/memstat.c b/tools/libmemstat/memstat.c index b3788661a..4e2291beb 100644 --- a/tools/libmemstat/memstat.c +++ b/tools/libmemstat/memstat.c @@ -38,6 +38,10 @@ #include #include +#ifdef FSTACK +#include +#endif + #include "memstat.h" #include "memstat_internal.h" diff --git a/tools/libmemstat/memstat_all.c b/tools/libmemstat/memstat_all.c index b0eb50f81..96d586a5e 100644 --- a/tools/libmemstat/memstat_all.c +++ b/tools/libmemstat/memstat_all.c @@ -31,6 +31,10 @@ #include #include +#ifdef FSTACK +#include +#endif + #include "memstat.h" /* @@ -48,6 +52,7 @@ memstat_sysctl_all(struct memory_type_list *mtlp, int flags) return (0); } +#ifndef FSTACK int memstat_kvm_all(struct memory_type_list *mtlp, void *kvm_handle) { @@ -58,3 +63,5 @@ memstat_kvm_all(struct memory_type_list *mtlp, void *kvm_handle) return (-1); return (0); } +#endif + diff --git a/tools/libmemstat/memstat_malloc.c b/tools/libmemstat/memstat_malloc.c index 6b8fe49ca..7b0d5108c 100644 --- a/tools/libmemstat/memstat_malloc.c +++ b/tools/libmemstat/memstat_malloc.c @@ -28,6 +28,10 @@ * $FreeBSD$ */ +#ifdef FSTACK +#include +#endif + #include #include #include @@ -35,7 +39,9 @@ #include #include +#ifndef FSTACK #include +#endif #include #include #include @@ -44,6 +50,7 @@ #include "memstat.h" #include "memstat_internal.h" +#ifndef FSTACK static int memstat_malloc_zone_count; static int memstat_malloc_zone_sizes[32]; @@ -63,6 +70,7 @@ static struct nlist namelist[] = { { .n_name = "_mp_maxcpus" }, { .n_name = "" }, }; +#endif /* * Extract malloc(9) statistics from the running kernel, and store all memory @@ -123,10 +131,12 @@ retry: return (-1); } +#ifndef FSTACK if (memstat_malloc_zone_init() == -1) { list->mtl_error = MEMSTAT_ERROR_VERSION; return (-1); } +#endif size = sizeof(*mthp) + count * (sizeof(*mthp) + sizeof(*mtsp) * maxcpus); @@ -246,6 +256,7 @@ retry: return (0); } +#ifndef FSTACK static int kread(kvm_t *kvm, void *kvm_pointer, void *address, size_t size, size_t offset) @@ -544,3 +555,5 @@ memstat_malloc_zone_used(const struct memory_type *mtp, size_t n) return (0); } +#endif + diff --git a/tools/libmemstat/memstat_uma.c b/tools/libmemstat/memstat_uma.c index b416cbc63..eb9a5b914 100644 --- a/tools/libmemstat/memstat_uma.c +++ b/tools/libmemstat/memstat_uma.c @@ -28,6 +28,10 @@ * $FreeBSD$ */ +#ifdef FSTACK +#include +#endif + #include #include #include @@ -38,7 +42,9 @@ #include #include +#ifndef FSTACK #include +#endif #include #include #include @@ -49,6 +55,7 @@ #include "memstat.h" #include "memstat_internal.h" +#ifndef FSTACK static struct nlist namelist[] = { #define X_UMA_KEGS 0 { .n_name = "_uma_kegs" }, @@ -60,6 +67,7 @@ static struct nlist namelist[] = { { .n_name = "_vm_ndomains" }, { .n_name = "" }, }; +#endif /* * Extract uma(9) statistics from the running kernel, and store all memory @@ -251,6 +259,7 @@ retry: return (0); } +#ifndef FSTACK static int kread(kvm_t *kvm, void *kvm_pointer, void *address, size_t size, size_t offset) @@ -488,3 +497,5 @@ skip_percpu: free(ucp_array); return (0); } +#endif + diff --git a/tools/libnetgraph/Makefile b/tools/libnetgraph/Makefile index fa760479f..7f82c6aab 100644 --- a/tools/libnetgraph/Makefile +++ b/tools/libnetgraph/Makefile @@ -1,13 +1,27 @@ # $FreeBSD$ # $Whistle: Makefile,v 1.4 1999/01/17 03:41:02 julian Exp $ +TOPDIR?=${CURDIR}/../.. + +ifneq ($(shell pkg-config --exists libdpdk && echo 0),0) +$(error "no installation of DPDK found, maybe you shuld export environment variable `PKG_CONFIG_PATH`") +endif + +PACKAGE=lib${LIB} LIB= netgraph WARNS?= 3 MAN= netgraph.3 SHLIB_MAJOR= 4 -SRCS= sock.c msg.c debug.c +PKGCONF ?= pkg-config + +DPDK_CFLAGS= -g -Wall -Werror $(shell $(PKGCONF) --cflags libdpdk) + +CFLAGS+= ${DPDK_CFLAGS} +CFLAGS+= -I${TOPDIR}/lib + +SRCS= sock.c msg.c debug.c compat.c INCS= netgraph.h MLINKS+= netgraph.3 NgMkSockNode.3 @@ -25,4 +39,4 @@ MLINKS+= netgraph.3 NgAllocRecvData.3 MLINKS+= netgraph.3 NgSetDebug.3 MLINKS+= netgraph.3 NgSetErrLog.3 -.include +include ${TOPDIR}/tools/lib.mk diff --git a/tools/libnetgraph/compat.c b/tools/libnetgraph/compat.c new file mode 100644 index 000000000..1574c6106 --- /dev/null +++ b/tools/libnetgraph/compat.c @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + */ + + +#include +#include +#include +#include + +#include "ff_api.h" +#include "ff_ipc.h" +#include "netgraph.h" + +static int +ngctl(int cmd, void *data, size_t len) +{ + struct ff_msg *msg, *retmsg = NULL; + + msg = ff_ipc_msg_alloc(); + if (msg == NULL) { + errno = ENOMEM; + return -1; + } + + if (len > msg->buf_len) { + errno = EINVAL; + ff_ipc_msg_free(msg); + return -1; + } + + msg->msg_type = FF_NGCTL; + msg->ngctl.cmd = cmd; + msg->ngctl.data = msg->buf_addr; + + switch (cmd) { + case NGCTL_SOCKET: + case NGCTL_CLOSE: + memcpy(msg->ngctl.data, data, len); + break; + case NGCTL_BIND: + case NGCTL_CONNECT: + { + struct bind_args *src = (struct bind_args *)data; + struct bind_args *dst = (struct bind_args *)(msg->ngctl.data); + dst->s = src->s; + dst->name = (char *)msg->buf_addr + sizeof(struct bind_args); + dst->namelen = src->namelen; + memcpy(dst->name, src->name, src->namelen); + break; + } + case NGCTL_SEND: + { + struct sendto_args *src = (struct sendto_args *)data; + struct sendto_args *dst = (struct sendto_args *)(msg->ngctl.data); + dst->s = src->s; + dst->buf = (char *)msg->buf_addr + sizeof(struct sendto_args); + dst->len = src->len; + dst->flags = src->flags; + dst->to = dst->buf + src->len; + dst->tolen = src->tolen; + memcpy(dst->buf, src->buf, src->len); + memcpy(dst->to, src->to, src->tolen); + break; + } + case NGCTL_RECV: + { + struct recvfrom_args *src = (struct recvfrom_args *)data; + struct recvfrom_args *dst = (struct recvfrom_args *)(msg->ngctl.data); + dst->s = src->s; + dst->buf = msg->buf_addr + sizeof(struct recvfrom_args); + dst->len = src->len; + dst->flags = src->flags; + dst->from = (struct sockaddr *)dst->buf + src->len; + dst->fromlenaddr = (socklen_t *)dst->buf + src->len + *(src->fromlenaddr); + memcpy(dst->buf, src->buf, src->len); + memcpy(dst->from, src->from, *(src->fromlenaddr)); + memcpy(dst->fromlenaddr, src->fromlenaddr, sizeof(socklen_t)); + break; + } + default: + errno = EINVAL; + ff_ipc_msg_free(msg); + return -1; + } + + int ret = ff_ipc_send(msg); + if (ret < 0) { + errno = EPIPE; + ff_ipc_msg_free(msg); + return -1; + } + + do { + if (retmsg != NULL) { + ff_ipc_msg_free(retmsg); + } + ret = ff_ipc_recv(&retmsg, msg->msg_type); + if (ret < 0) { + errno = EPIPE; + return -1; + } + } while (msg != retmsg); + + if (retmsg->result != 0) { + ret = -1; + errno = retmsg->result; + } else { + ret = msg->ngctl.ret; + + if (cmd == NGCTL_RECV) { + struct recvfrom_args *dst = (struct recvfrom_args *)data; + struct recvfrom_args *src = (struct recvfrom_args *)(msg->ngctl.data); + memcpy(dst->buf, src->buf, src->len); + memcpy(dst->from, src->from, *(src->fromlenaddr)); + memcpy(dst->fromlenaddr, src->fromlenaddr, sizeof(socklen_t)); + } + } + + ff_ipc_msg_free(msg); + + return ret; +} + +int +ng_socket(int domain, int type, int protocol) +{ + struct socket_args sa; + sa.domain = domain; + sa.type = type; + sa.protocol = protocol; + + return ngctl(NGCTL_SOCKET, (void *)&sa, sizeof(sa)); +} + +int +ng_bind(int sockfd, const struct sockaddr *addr, + socklen_t addrlen) +{ + size_t len; + struct bind_args ba; + + ba.s = sockfd; + ba.name = (char *)addr; + ba.namelen = addrlen; + + len = sizeof(ba) + addrlen; + + return ngctl(NGCTL_BIND, (void *)&ba, len); +} + +int +ng_connect(int sockfd, const struct sockaddr *addr, + socklen_t addrlen) +{ + size_t len; + struct connect_args ca; + + ca.s = sockfd; + ca.name = (char *)addr; + ca.namelen = addrlen; + + len = sizeof(ca) + addrlen; + + return ngctl(NGCTL_CONNECT, (void *)&ca, len); +} + +ssize_t +ng_sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) +{ + size_t datalen; + + struct sendto_args sa; + sa.s = sockfd; + sa.buf = (void *)buf; + sa.len = len; + sa.flags = flags; + sa.to = (char *)dest_addr; + sa.tolen = addrlen; + + datalen = sizeof(sa) + len + addrlen; + return ngctl(NGCTL_SEND, (void *)&sa, datalen); +} + +ssize_t +ng_recvfrom(int sockfd, void *buf, size_t len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) +{ + size_t datalen; + + struct recvfrom_args ra; + ra.s = sockfd; + ra.buf = buf; + ra.len = len; + ra.flags = flags; + ra.from = src_addr; + ra.fromlenaddr = addrlen; + + datalen = sizeof(ra) + len + (*addrlen) + sizeof(socklen_t); + return ngctl(NGCTL_RECV, (void *)&ra, datalen); +} + +int +ng_close(int fd) +{ + struct close_args ca; + ca.fd = fd; + + return ngctl(NGCTL_CLOSE, (void *)&ca, sizeof(ca)); +} + diff --git a/tools/libnetgraph/internal.h b/tools/libnetgraph/internal.h index 748ca7bb7..a8d6778d7 100644 --- a/tools/libnetgraph/internal.h +++ b/tools/libnetgraph/internal.h @@ -72,3 +72,14 @@ extern void _NgDebugSockaddr(const struct sockaddr_ng *sg); extern void _NgDebugMsg(const struct ng_mesg *msg, const char *path); extern void _NgDebugBytes(const u_char *ptr, int size); +#ifdef FSTACK + +#define socket(a,b,c) ng_socket(a,b,c) +#define connect(a,b,c) ng_connect(a,b,c) +#define bind(a,b,c) ng_bind(a,b,c) +#define sendto(a,b,c,d,e,f) ng_sendto(a,b,c,d,e,f) +#define recvfrom(a,b,c,d,e,f) ng_recvfrom(a,b,c,d,e,f) +#define close(a) ng_close(a) + +#endif + diff --git a/tools/libnetgraph/msg.c b/tools/libnetgraph/msg.c index 061bdc233..12917e571 100644 --- a/tools/libnetgraph/msg.c +++ b/tools/libnetgraph/msg.c @@ -38,19 +38,43 @@ * $Whistle: msg.c,v 1.9 1999/01/20 00:57:23 archie Exp $ */ +#ifdef FSTACK +#define _GNU_SOURCE +#include +#endif + #include __FBSDID("$FreeBSD$"); #include #include #include +#ifndef FSTACK #include +#endif #include #include #include "netgraph.h" #include "internal.h" +#ifdef FSTACK +#define _Atomic(T) T volatile + +#ifndef __ATOMIC_SEQ_CST +#define __ATOMIC_SEQ_CST 5 +#endif + +typedef enum { + memory_order_seq_cst = __ATOMIC_SEQ_CST +} memory_order; + +#define atomic_fetch_add(object, operand) \ + atomic_fetch_add_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_add_explicit(object, operand, order) \ + __atomic_fetch_add(object, operand, order) +#endif + /* Next message token value */ static _Atomic(unsigned int) gMsgId; @@ -230,6 +254,7 @@ NgDeliverMsg(int cs, const char *path, goto done; } +#ifndef FSTACK /* Wait for reply if there should be one. */ if (msg->header.cmd & NGM_HASREPLY && !(msg->header.flags & NGF_RESP)) { struct pollfd rfds; @@ -246,6 +271,7 @@ NgDeliverMsg(int cs, const char *path, rtn = -1; } } +#endif done: /* Done */ @@ -302,10 +328,15 @@ int NgAllocRecvMsg(int cs, struct ng_mesg **rep, char *path) { int len; +#ifndef FSTACK socklen_t optlen; optlen = sizeof(len); if (getsockopt(cs, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1 || +#else + len = NGCTL_DEFAULT_RCVBUF; + if ( +#endif (*rep = malloc(len)) == NULL) return (-1); if ((len = NgRecvMsg(cs, *rep, len, path)) < 0) @@ -365,10 +396,15 @@ int NgAllocRecvAsciiMsg(int cs, struct ng_mesg **reply, char *path) { int len; +#ifndef FSTACK socklen_t optlen; optlen = sizeof(len); if (getsockopt(cs, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1 || +#else + len = NGCTL_DEFAULT_RCVBUF; + if ( +#endif (*reply = malloc(len)) == NULL) return (-1); if ((len = NgRecvAsciiMsg(cs, *reply, len, path)) < 0) diff --git a/tools/libnetgraph/netgraph.h b/tools/libnetgraph/netgraph.h index 4eb15bd8b..7c699ae40 100644 --- a/tools/libnetgraph/netgraph.h +++ b/tools/libnetgraph/netgraph.h @@ -46,6 +46,14 @@ #include #include +#ifdef FSTACK +#ifndef __printflike +#define __printflike(fmtarg, firstvararg) +#endif + +#define NGCTL_DEFAULT_RCVBUF 1024*8 +#endif + __BEGIN_DECLS int NgMkSockNode(const char *, int *, int *); int NgNameNode(int, const char *, const char *, ...) __printflike(3, 4); @@ -63,6 +71,22 @@ int NgAllocRecvData(int, u_char **, char *); int NgSetDebug(int); void NgSetErrLog(void (*)(const char *fmt, ...), void (*)(const char *fmt, ...)); + +#ifdef FSTACK +#include + +int ng_socket(int domain, int type, int protocol); +int ng_connect(int sockfd, const struct sockaddr *addr, + socklen_t addrlen); +int ng_bind(int sockfd, const struct sockaddr *addr, + socklen_t addrlen); +ssize_t ng_sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen); +ssize_t ng_recvfrom(int sockfd, void *buf, size_t len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen); +int ng_close(int fd); +#endif + __END_DECLS #endif diff --git a/tools/libnetgraph/sock.c b/tools/libnetgraph/sock.c index 12603d3b1..058fdcb1d 100644 --- a/tools/libnetgraph/sock.c +++ b/tools/libnetgraph/sock.c @@ -74,6 +74,7 @@ NgMkSockNode(const char *name, int *csp, int *dsp) If we get an EAFNOSUPPORT then the socket node type is not loaded, so load it and try again. */ if ((cs = socket(AF_NETGRAPH, SOCK_DGRAM, NG_CONTROL)) < 0) { +#ifndef FSTACK if (errno == EAFNOSUPPORT) { if (kldload(NG_SOCKET_KLD) < 0) { errnosv = errno; @@ -85,13 +86,16 @@ NgMkSockNode(const char *name, int *csp, int *dsp) if (cs >= 0) goto gotNode; } +#endif errnosv = errno; if (_gNgDebugLevel >= 1) NGLOG("socket"); goto errout; } +#ifndef FSTACK gotNode: +#endif /* Assign the node the desired name, if any */ if (name != NULL) { u_char sbuf[NG_NODESIZ + NGSA_OVERHEAD]; @@ -253,10 +257,15 @@ int NgAllocRecvData(int ds, u_char **buf, char *hook) { int len; +#ifndef FSTACK socklen_t optlen; optlen = sizeof(len); if (getsockopt(ds, SOL_SOCKET, SO_RCVBUF, &len, &optlen) == -1 || +#else + len = NGCTL_DEFAULT_RCVBUF; + if ( +#endif (*buf = malloc(len)) == NULL) return (-1); if ((len = NgRecvData(ds, *buf, len, hook)) < 0) diff --git a/tools/libutil/Makefile b/tools/libutil/Makefile index df3fb622b..eefd03eed 100644 --- a/tools/libutil/Makefile +++ b/tools/libutil/Makefile @@ -3,7 +3,8 @@ SHLIBDIR?= /lib -.include +TOPDIR?=${CURDIR}/../.. +include ${TOPDIR}/tools/opts.mk PACKAGE= runtime @@ -12,7 +13,7 @@ PACKAGE= runtime LIB= util SHLIB_MAJOR= 9 -SRCS= _secure_path.c auth.c expand_number.c flopen.c fparseln.c \ +#SRCS= _secure_path.c auth.c expand_number.c flopen.c fparseln.c \ getlocalbase.c gr_util.c \ hexdump.c humanize_number.c kinfo_getfile.c \ kinfo_getallproc.c kinfo_getproc.c kinfo_getvmmap.c \ @@ -21,15 +22,18 @@ SRCS= _secure_path.c auth.c expand_number.c flopen.c fparseln.c \ login_class.c login_crypt.c login_ok.c login_times.c login_tty.c \ pidfile.c property.c pty.c pw_scan.c pw_util.c quotafile.c \ realhostname.c stub.c trimdomain.c uucplock.c +SRCS= _secure_path.c auth.c expand_number.c flopen.c fparseln.c \ + hexdump.c humanize_number.c \ + stub.c trimdomain.c INCS= libutil.h login_cap.h CFLAGS+= -DNO__SCCSID -.if ${MK_INET6_SUPPORT} != "no" +ifneq (${MK_INET6_SUPPORT},"no") CFLAGS+= -DINET6 -.endif +endif -CFLAGS+= -I${.CURDIR} -I${SRCTOP}/lib/libc/gen/ +CFLAGS+= -I${CURDIR} -I${SRCTOP}/lib/libc/gen/ MAN+= expand_number.3 flopen.3 fparseln.3 getlocalbase.3 hexdump.3 \ humanize_number.3 kinfo_getallproc.3 kinfo_getfile.3 \ @@ -89,7 +93,8 @@ MLINKS+=pw_util.3 pw_copy.3 \ pw_util.3 pw_tempname.3 \ pw_util.3 pw_tmp.3 -HAS_TESTS= -SUBDIR.${MK_TESTS}+= tests +ifneq (${MK_TESTS},"no") +SUBDIR+= tests +endif -.include +include ${TOPDIR}/tools/lib.mk diff --git a/tools/libutil/fparseln.c b/tools/libutil/fparseln.c index 436ec2018..1ce28dcc9 100644 --- a/tools/libutil/fparseln.c +++ b/tools/libutil/fparseln.c @@ -87,6 +87,10 @@ fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags) char *ptr, *cp; int cnt; char esc, con, nl, com; +#ifdef FSTACK + #define MAXLINELEN 4096 + char fbuf[MAXLINELEN]; +#endif #if 0 _DIAGASSERT(fp != NULL); @@ -114,8 +118,15 @@ fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags) if (lineno) (*lineno)++; +#ifndef FSTACK if ((ptr = fgetln(fp, &s)) == NULL) break; +#else + if (fgets(fbuf, MAXLINELEN, fp) == NULL) + break; + fbuf[strcspn(fbuf, "\n")] = '\0'; + ptr = fbuf; +#endif if (s && com) { /* Check and eliminate comments */ for (cp = ptr; cp < ptr + s; cp++) diff --git a/tools/libutil/libutil.h b/tools/libutil/libutil.h index bb96b2caa..4e7cf1419 100644 --- a/tools/libutil/libutil.h +++ b/tools/libutil/libutil.h @@ -43,7 +43,11 @@ #include #include +#ifndef FSTACK #include +#else +#include +#endif #ifndef _GID_T_DECLARED typedef __gid_t gid_t; diff --git a/tools/libutil/stub.c b/tools/libutil/stub.c index 55d6e0c45..c4c5856b7 100644 --- a/tools/libutil/stub.c +++ b/tools/libutil/stub.c @@ -33,6 +33,12 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef FSTACK +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif +#endif + /* * Stub out what's in -lcrypt. */ diff --git a/tools/libxo/.gitignore b/tools/libxo/.gitignore new file mode 100644 index 000000000..8d70b6cc1 --- /dev/null +++ b/tools/libxo/.gitignore @@ -0,0 +1,46 @@ +# Object files +*.o + +# Libraries +*.lib +*.a + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.app + +*~ +*.orig + +aclocal.m4 +ar-lib +autom4te.cache +build +compile +config.guess +config.h.in +config.sub +depcomp +install-sh +ltmain.sh +missing +m4 + +Makefile.in +configure +.DS_Store + +xoconfig.h.in +xo_config.h.in + +.gdbinit +.gdbinit.local +xtest +xtest.dSYM +tests/w diff --git a/tools/libxo/.svnignore b/tools/libxo/.svnignore new file mode 100644 index 000000000..8327c93fd --- /dev/null +++ b/tools/libxo/.svnignore @@ -0,0 +1,18 @@ +Makefile.in +aclocal.m4 +ar-lib +autom4te.cache +bin* +build* +compile +configure +config.guess +config.sub +depcomp +doc/Makefile.in +info* +install-sh +ltmain.sh +m4 +missing +patches* diff --git a/tools/libxo/.travis.yml b/tools/libxo/.travis.yml new file mode 100644 index 000000000..1173578bb --- /dev/null +++ b/tools/libxo/.travis.yml @@ -0,0 +1,12 @@ +language: c + +script: printenv && uname -a && ls -l && /bin/sh -x ./bin/setup.sh && cd build && ../configure --enable-warnings && make && sudo make install && make test + +notifications: + recipients: + - libslax-noise@googlegroups.com + +branches: + only: + - master + - develop diff --git a/tools/libxo/Copyright b/tools/libxo/Copyright new file mode 100644 index 000000000..94ba75e4f --- /dev/null +++ b/tools/libxo/Copyright @@ -0,0 +1,23 @@ +Copyright (c) 2014 Juniper Networks, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/tools/libxo/INSTALL.md b/tools/libxo/INSTALL.md new file mode 100644 index 000000000..70b80bcea --- /dev/null +++ b/tools/libxo/INSTALL.md @@ -0,0 +1,15 @@ + + +## Instructions for building libxo + +Instructions for building libxo are now available in the +[wiki](http://juniper.github.io/libxo/libxo-manual.html#getting-libxo). diff --git a/tools/libxo/LICENSE b/tools/libxo/LICENSE new file mode 100644 index 000000000..874da7b2d --- /dev/null +++ b/tools/libxo/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2014, Juniper Networks +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tools/libxo/Makefile b/tools/libxo/Makefile index 954e3d5ee..1dfceb916 100644 --- a/tools/libxo/Makefile +++ b/tools/libxo/Makefile @@ -1,10 +1,25 @@ # $FreeBSD$ -.include +PACKAGE=lib${LIB} +SHLIBDIR?= /lib -HAS_TESTS= -SUBDIR.${MK_TESTS}+= tests +TOPDIR?=${CURDIR}/../.. +include ${TOPDIR}/tools/opts.mk -SUBDIR = libxo .WAIT encoder +LIBXOSRC= ./libxo +VPATH+= ${LIBXOSRC} + +LIB= xo +SHLIB_MAJOR=0 + +#SRCS= ${LIBXOSRC}/libxo.c ${LIBXOSRC}/xo_encoder.c ${LIBXOSRC}/xo_syslog.c +SRCS= libxo.c xo_encoder.c xo_syslog.c + +CFLAGS+= -I${LIBXOSRC} -I${CURDIR} +#CFLAGS+= -DXO_ENCODERDIR=\"/usr/lib/libxo/encoder\" +CFLAGS+= -DXO_ENCODERDIR=\"\" + +CFLAGS+= -I${TOPDIR}/tools/libutil + +include ${TOPDIR}/tools/lib.mk -.include diff --git a/tools/libxo/Makefile.am b/tools/libxo/Makefile.am new file mode 100644 index 000000000..8a5247388 --- /dev/null +++ b/tools/libxo/Makefile.am @@ -0,0 +1,144 @@ +# +# $Id$ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = libxo xo xopo xolint xohtml tests doc encoder +bin_SCRIPTS=libxo-config +dist_doc_DATA = Copyright + +EXTRA_DIST = \ + libxo-config.in \ + warnings.mk \ + README.md \ + INSTALL.md \ + packaging/libxo.spec + +.PHONY: test tests + +test tests: + @(cd tests ; ${MAKE} test) + +errors: + @(cd tests/errors ; ${MAKE} test) + +docs: + @(cd doc ; ${MAKE} docs) + +DIST_FILES_DIR = ~/Dropbox/dist-files/ +GH_PAGES_DIR = gh-pages/ +GH_PAGES_DIR_VER = gh-pages/${PACKAGE_VERSION} +PACKAGE_FILE = ${PACKAGE_TARNAME}-${PACKAGE_VERSION}.tar.gz + +XOHTML_FILES = \ + ${top_srcdir}/xohtml/xohtml.css \ + ${top_srcdir}/xohtml/xohtml.js \ + ${top_srcdir}/xohtml/external/jquery.js \ + ${top_srcdir}/xohtml/external/jquery.qtip.css \ + ${top_srcdir}/xohtml/external/jquery.qtip.js + +upload: dist upload-docs upload-xohtml-files + @echo "Remember to run:" + @echo " gt tag ${PACKAGE_VERSION}" + +upload-docs: docs upload-html + +upload-html: + @echo "Uploading html ... " + @-[ -d ${GH_PAGES_DIR} -a -d doc/html ] \ + && echo "Updating html on gh-pages ..." \ + && mkdir -p ${GH_PAGES_DIR_VER}/html \ + && cp doc/top-link.html ${GH_PAGES_DIR}/libxo.html \ + && cp -r doc/html/* ${GH_PAGES_DIR_VER}/html/ \ + && (cd ${GH_PAGES_DIR} \ + && git add libxo.html \ + && git add ${PACKAGE_VERSION}/html \ + && git commit -m 'new docs' \ + libxo.html ${PACKAGE_VERSION}/html \ + && git push origin gh-pages ) ; true + +upload-xohtml-files: + @echo "Uploading xohtml files ... " + @-[ -d ${GH_PAGES_DIR} ] \ + && echo "Updating xohtml files on gh-pages ..." \ + && mkdir -p ${GH_PAGES_DIR_VER}/xohtml \ + && cp ${XOHTML_FILES} ${GH_PAGES_DIR_VER}/xohtml \ + && (cd ${GH_PAGES_DIR} \ + && git add ${PACKAGE_VERSION}/xohtml \ + && git commit -m 'new xohtml files' \ + ${PACKAGE_VERSION}/xohtml \ + && git push origin gh-pages ) ; true + +pkgconfigdir=$(libdir)/pkgconfig +pkgconfig_DATA = packaging/${PACKAGE_NAME}.pc + +get-wiki: + git clone https://github.com/Juniper/${PACKAGE_NAME}.wiki.git wiki + +get-gh-pages: + git clone https://github.com/Juniper/${PACKAGE_NAME}.git \ + gh-pages -b gh-pages + +UPDATE_PACKAGE_FILE = \ + -e "s;__SHA1__;$$SHA1;" \ + -e "s;__SHA256__;SHA256 (textproc/${PACKAGE_FILE}) = $$SHA256;" \ + -e "s;__SIZE__;SIZE (textproc/${PACKAGE_FILE}) = $$SIZE;" + +GH_PACKAGING_DIR = ${PACKAGE_VERSION}/packaging +GH_PAGES_PACKAGE_DIR = ${GH_PAGES_DIR}/${GH_PACKAGING_DIR} + +packages: + @-[ -d ${GH_PAGES_DIR} ] && set -x \ + && echo "Updating packages on gh-pages ..." \ + && mkdir -p ${GH_PAGES_DIR}/${GH_PACKAGING_DIR} \ + && SHA1="`openssl sha1 ${PACKAGE_FILE} | awk '{print $$2}'`" \ + && SHA256="`openssl sha256 ${PACKAGE_FILE} | awk '{print $$2}'`" \ + && SIZE="`ls -l ${PACKAGE_FILE} | awk '{print $$5}'`" \ + && echo "... ${GH_PAGES_PACKAGE_DIR}/${PACKAGE_NAME}.rb ..." \ + && sed ${UPDATE_PACKAGE_FILE} \ + packaging/${PACKAGE_NAME}.rb.base \ + > ${GH_PAGES_PACKAGE_DIR}/${PACKAGE_NAME}.rb \ + && echo "... ${GH_PAGES_PACKAGE_DIR}/${PACKAGE_NAME}.spec ..." \ + && cp packaging/${PACKAGE_NAME}.spec \ + ${GH_PAGES_PACKAGE_DIR}/${PACKAGE_NAME}.spec \ + && (cd ${GH_PAGES_DIR} \ + && git add ${GH_PACKAGING_DIR} \ + && git add ${GH_PACKAGING_DIR}/libxo.rb \ + ${GH_PACKAGING_DIR}/libxo.spec \ + && git commit -m 'new packaging data' \ + ${GH_PACKAGING_DIR} \ + && git push origin gh-pages ) ; true + +ANALYZE_DIR = ~/trash/libxo +ANALYZE_CMD = scan-build-mp-3.6 + +analyze: + ${MAKE} clean + ${ANALYZE_CMD} -o ${ANALYZE_DIR} ${MAKE} + +SANIFLAGS=-fno-omit-frame-pointer -g -O2 + +sanitize-address: + ${MAKE} clean + ${MAKE} CFLAGS="-fsanitize=address ${SANIFLAGS}" + ${MAKE} install + ${MAKE} test + +sanitize-undefined: + ${MAKE} clean + ${MAKE} CFLAGS="-fsanitize=undefined ${SANIFLAGS}" + ${MAKE} install + ${MAKE} test + +sanitize-memory: + ${MAKE} clean + ${MAKE} CFLAGS="-fsanitize=memory ${SANIFLAGS}" + ${MAKE} install + ${MAKE} test diff --git a/tools/libxo/Makefile.depend b/tools/libxo/Makefile.depend deleted file mode 100644 index bcfa88f57..000000000 --- a/tools/libxo/Makefile.depend +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - lib/libutil \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/tools/libxo/README.md b/tools/libxo/README.md new file mode 100644 index 000000000..fdba97a00 --- /dev/null +++ b/tools/libxo/README.md @@ -0,0 +1,67 @@ +libxo +===== + +libxo - A Library for Generating Text, XML, JSON, and HTML Output + +The libxo library allows an application to generate text, XML, JSON, +and HTML output using a common set of function calls. The application +decides at run time which output style should be produced. The +application calls a function "xo_emit" to product output that is +described in a format string. A "field descriptor" tells libxo what +the field is and what it means. + +Imagine a simplified ``wc`` that emits its output fields in a single +xo_emit call: + +``` + xo_emit(" {:lines/%7ju/%ju} {:words/%7ju/%ju} " + "{:characters/%7ju/%ju}{d:filename/%s}\n", + linect, wordct, charct, file); +``` + +Output can then be generated in various style, using the "--libxo" +option: + +``` + % wc /etc/motd + 25 165 1140 /etc/motd + % wc --libxo xml,pretty,warn /etc/motd + + + /etc/motd + 25 + 165 + 1140 + + + % wc --libxo json,pretty,warn /etc/motd + { + "wc": { + "file": [ + { + "filename": "/etc/motd", + "lines": 25, + "words": 165, + "characters": 1140 + } + ] + } + } + % wc --libxo html,pretty,warn /etc/motd +
+
+
25
+
+
165
+
+
1140
+
+
/etc/motd
+
+``` + +View the beautiful documentation at: + +http://juniper.github.io/libxo/libxo-manual.html + +[![Analytics](https://ga-beacon.appspot.com/UA-56056421-1/Juniper/libxo/Readme)](https://github.com/Juniper/libxo) diff --git a/tools/libxo/configure.ac b/tools/libxo/configure.ac new file mode 100644 index 000000000..e28db9396 --- /dev/null +++ b/tools/libxo/configure.ac @@ -0,0 +1,500 @@ +# +# $Id$ +# +# See ./INSTALL for more info +# + +# +# Release numbering: even numbered dot releases are official ones, and +# odd numbers are development ones. The svn version of this file will +# only (ONLY!) ever (EVER!) contain odd numbers, so I'll always know if +# a particular user has the dist or svn release. +# + +AC_PREREQ(2.2) +AC_INIT([libxo], [1.4.0], [phil@juniper.net]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability]) + +# Support silent build rules. Requires at least automake-1.11. +# Disable with "configure --disable-silent-rules" or "make V=1" +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AC_PROG_CC +AC_PROG_INSTALL +AC_CONFIG_MACRO_DIR([m4]) +AC_PROG_LN_S + +# Must be after AC_PROG_AR +LT_INIT([dlopen shared]) + +AC_PATH_PROG(BASENAME, basename, /usr/bin/basename) +AC_PATH_PROG(BISON, bison, /usr/bin/bison) +AC_PATH_PROG(CAT, cat, /bin/cat) +AC_PATH_PROG(CHMOD, chmod, /bin/chmod) +AC_PATH_PROG(CP, cp, /bin/cp) +AC_PATH_PROG(DIFF, diff, /usr/bin/diff) +AC_PATH_PROG(MKDIR, mkdir, /bin/mkdir) +AC_PATH_PROG(MV, mv, /bin/mv) +AC_PATH_PROG(RM, rm, /bin/rm) +AC_PATH_PROG(SED, sed, /bin/sed) + +AC_STDC_HEADERS + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_INLINE +AC_TYPE_SIZE_T + +# Checks for library functions. +AC_FUNC_ALLOCA +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_CHECK_FUNCS([bzero memmove strchr strcspn strerror strspn]) +AC_CHECK_FUNCS([sranddev srand strlcpy]) +AC_CHECK_FUNCS([fdopen getrusage]) +AC_CHECK_FUNCS([gettimeofday ctime]) +AC_CHECK_FUNCS([getpass]) +AC_CHECK_FUNCS([getprogname]) +AC_CHECK_FUNCS([sysctlbyname]) +AC_CHECK_FUNCS([flock]) +AC_CHECK_FUNCS([asprintf]) +AC_CHECK_FUNCS([__flbf]) +AC_CHECK_FUNCS([sysctlbyname]) + + +AC_CHECK_HEADERS([dlfcn.h]) +AC_CHECK_HEADERS([dlfcn.h]) +AC_CHECK_HEADERS([stdio_ext.h]) +AC_CHECK_HEADERS([tzfile.h]) +AC_CHECK_HEADERS([stdtime/tzfile.h]) +AC_CHECK_FUNCS([dlfunc]) + +AC_CHECK_HEADERS([sys/time.h]) +AC_CHECK_HEADERS([ctype.h errno.h stdio.h stdlib.h]) +AC_CHECK_HEADERS([string.h sys/param.h unistd.h ]) +AC_CHECK_HEADERS([sys/sysctl.h]) +AC_CHECK_HEADERS([threads.h]) +AC_CHECK_HEADERS([monitor.h]) + +dnl humanize_number(3) is a great function, but it's not standard. +dnl Note Macosx has the function in libutil.a but doesn't ship the +dnl header file, so I'll need to carry my own implementation. See: +dnl https://devforums.apple.com/thread/271121 +AC_CHECK_HEADERS([libutil.h]) +AC_CHECK_LIB([util], [humanize_number], + [HAVE_HUMANIZE_NUMBER=$ac_cv_header_libutil_h], + [HAVE_HUMANIZE_NUMBER=no]) + +AC_MSG_RESULT(humanize_number results: :${HAVE_HUMANIZE_NUMBER}:${ac_cv_header_libutil_h}:) + +if test "$HAVE_HUMANIZE_NUMBER" = "yes"; then + AC_DEFINE([HAVE_HUMANIZE_NUMBER], [1], [humanize_number(3)]) +fi + +AM_CONDITIONAL([HAVE_HUMANIZE_NUMBER], [test "$HAVE_HUMANIZE_NUMBER" = "yes"]) + +AC_ARG_ENABLE([gettext], + [ --disable-gettext Turn off support for gettext], + [GETTEXT_ENABLE=$enableval], + [GETTEXT_ENABLE=yes]) + +dnl Looking for gettext(), assumably in libintl +AC_ARG_WITH(gettext, + [ --with-gettext=[PFX] Specify location of gettext installation], + [GETTEXT_PREFIX=$withval], + [GETTEXT_PREFIX=/usr], +) + +HAVE_GETTEXT=no + +if test "$GETTEXT_ENABLE" != "no"; then + + AC_MSG_CHECKING([gettext in ${GETTEXT_PREFIX}]) + + _save_cflags="$CFLAGS" + CFLAGS="$CFLAGS -I${GETTEXT_PREFIX}/include -L${GETTEXT_PREFIX}/lib -Werror -lintl" + AC_LINK_IFELSE([AC_LANG_SOURCE([[#include ] + [int main() {char *cp = dgettext(NULL, "xx"); return 0; }]])], + [HAVE_GETTEXT=yes], + [HAVE_GETTEXT=no]) + CFLAGS="$_save_cflags" + + AC_MSG_RESULT([$HAVE_GETTEXT]) + + if test "$HAVE_GETTEXT" != "yes"; then + GETTEXT_PREFIX=/opt/local + AC_MSG_CHECKING([gettext in ${GETTEXT_PREFIX}]) + + _save_cflags="$CFLAGS" + CFLAGS="$CFLAGS -I${GETTEXT_PREFIX}/include -L${GETTEXT_PREFIX}/lib -Werror -lintl" + AC_LINK_IFELSE([AC_LANG_SOURCE([[#include ] + [int main() {char *cp = dgettext(NULL, "xx"); return 0; }]])], + [HAVE_GETTEXT=yes], + [HAVE_GETTEXT=no]) + CFLAGS="$_save_cflags" + + AC_MSG_RESULT([$HAVE_GETTEXT]) + fi + + if test "$HAVE_GETTEXT" != "yes"; then + GETTEXT_PREFIX=/usr/local + AC_MSG_CHECKING([gettext in ${GETTEXT_PREFIX}]) + + _save_cflags="$CFLAGS" + CFLAGS="$CFLAGS -I${GETTEXT_PREFIX}/include -L${GETTEXT_PREFIX}/lib -Werror -lintl" + AC_LINK_IFELSE([AC_LANG_SOURCE([[#include ] + [int main() {char *cp = dgettext(NULL, "xx"); return 0; }]])], + [HAVE_GETTEXT=yes], + [HAVE_GETTEXT=no]) + CFLAGS="$_save_cflags" + + AC_MSG_RESULT([$HAVE_GETTEXT]) + fi +fi + +if test "$HAVE_GETTEXT" = "yes"; then + AC_DEFINE([HAVE_GETTEXT], [1], [gettext(3)]) + GETTEXT_CFLAGS="-I${GETTEXT_PREFIX}/include" + GETTEXT_LIBS="-L${GETTEXT_PREFIX}/lib -lintl" +else + GETTEXT_PREFIX=none + GETTEXT_CFLAGS= + GETTEXT_LIBS= +fi +AC_SUBST(GETTEXT_CFLAGS) +AC_SUBST(GETTEXT_LIBS) + +GETTEXT_LIBDIR=${GETTEXT_PREFIX}/lib +AC_SUBST(GETTEXT_LIBDIR) +if test -x ${GETTEXT_PREFIX}/bin/msgfmt ; then + GETTEXT_BINDIR=${GETTEXT_PREFIX}/bin +elif test -x ${GETTEXT_PREFIX}/local/bin/msgfmt ; then + GETTEXT_BINDIR=${GETTEXT_PREFIX}/local/bin +else + AC_MSG_NOTICE("could not find msgfmt tool") + # Use a (bad) fall back value + GETTEXT_BINDIR=${GETTEXT_PREFIX}/bin +fi +AC_SUBST(GETTEXT_BINDIR) + +AM_CONDITIONAL([HAVE_GETTEXT], [test "$HAVE_GETTEXT" = "yes"]) + +dnl Looking for how to do thread-local variables +AC_ARG_WITH(threads, + [ --with-threads=[STYLE] Specify style of thread-local support (none)], + [THREAD_LOCAL=$withval], + [THREAD_LOCAL=unknown], +) + +AC_MSG_CHECKING([thread-locals are ${THREAD_LOCAL}]) + +if test "$THREAD_LOCAL" = "unknown"; then + AC_LINK_IFELSE([AC_LANG_SOURCE([[] + [__thread int foo; int main() { foo++; return foo; }]])], + [THREAD_LOCAL=before], + [THREAD_LOCAL=unknown]) + + AC_MSG_RESULT([$THREAD_LOCAL]) +fi + +if test "$THREAD_LOCAL" = "unknown"; then + AC_LINK_IFELSE([AC_LANG_SOURCE([[] + [int __thread foo; int main() { foo++; return foo; }]])], + [THREAD_LOCAL=after], + [THREAD_LOCAL=unknown]) + AC_MSG_RESULT([$THREAD_LOCAL]) +fi + +if test "$THREAD_LOCAL" = "unknown"; then + AC_LINK_IFELSE([AC_LANG_SOURCE([[] + [__declspec(int) foo; int main() { foo++; return foo; }]])], + [THREAD_LOCAL=declspec], + [THREAD_LOCAL=unknown]) + AC_MSG_RESULT([$THREAD_LOCAL]) +fi + +if test "$THREAD_LOCAL" != "unknown"; then + AC_DEFINE_UNQUOTED([HAVE_THREAD_LOCAL], + THREAD_LOCAL_${THREAD_LOCAL}, [thread-local setting]) +fi + +dnl Looking for libcrypto.... +AC_CHECK_LIB([crypto], [MD5_Init]) +AM_CONDITIONAL([HAVE_LIBCRYPTO], [test "$HAVE_LIBCRYPTO" != "no"]) + +AC_CHECK_MEMBER([struct sockaddr_un.sun_len], + [HAVE_SUN_LEN=yes ; + AC_DEFINE([HAVE_SUN_LEN], [1], [Have struct sockaddr_un.sun_len])], + [HAS_SUN_LEN=no], [[#include ]]) + +AC_CHECK_DECLS([__isthreaded], [], [], [#include ]) +HAVE_ISTHREADED=${ac_cv_have_decl___isthreaded} + +dnl +dnl Some packages need to be checked against version numbers so we +dnl define a function here for later use +dnl +AC_DEFUN([VERSION_TO_NUMBER], +[`$1 | sed -e 's/lib.* //' | awk 'BEGIN { FS = "."; } { printf "%d", ([$]1 * 1000 + [$]2) * 1000 + [$]3;}'`]) + +LIBSLAX_CONFIG_PREFIX="" +LIBSLAX_SRC="" + +AC_ARG_WITH(libslax-prefix, + [ --with-libslax-prefix=[PFX] Specify location of libslax config], + LIBSLAX_CONFIG_PREFIX=$withval +) + +AC_MSG_CHECKING(for libslax) +if test "x$LIBSLAX_CONFIG_PREFIX" != "x" +then + SLAX_CONFIG=${LIBSLAX_CONFIG_PREFIX}/bin/slax-config +else + SLAX_CONFIG=slax-config +fi + +dnl +dnl make sure slax-config is executable, +dnl test version and init our variables +dnl + +if ${SLAX_CONFIG} --libs > /dev/null 2>&1 +then + LIBSLAX_VERSION=`$SLAX_CONFIG --version` + SLAX_BINDIR="`$SLAX_CONFIG --bindir | head -1`" + SLAX_OXTRADOCDIR="`$SLAX_CONFIG --oxtradoc | head -1`" + AC_MSG_RESULT($LIBSLAX_VERSION found) + HAVE_OXTRADOC=yes +else + LIBSLAX_VERSION= + SLAX_BINDIR= + SLAX_OXTRADOCDIR= + AC_MSG_RESULT([no]) + HAVE_OXTRADOC=no +fi +AM_CONDITIONAL([HAVE_OXTRADOC], [test "$HAVE_OXTRADOC" != "no"]) + +AC_SUBST(SLAX_BINDIR) +AC_SUBST(SLAX_OXTRADOCDIR) + +AC_MSG_CHECKING([whether to build with warnings]) +AC_ARG_ENABLE([warnings], + [ --enable-warnings Turn on compiler warnings], + [LIBXO_WARNINGS=$enableval], + [LIBXO_WARNINGS=no]) +AC_MSG_RESULT([$LIBXO_WARNINGS]) +AM_CONDITIONAL([LIBXO_WARNINGS_HIGH], [test "$LIBXO_WARNINGS" != "no"]) + +AC_MSG_CHECKING([whether to build with debugging]) +AC_ARG_ENABLE([debug], + [ --enable-debug Turn on debugging], + [LIBXO_DEBUG=yes; AC_DEFINE([LIBXO_DEBUG], [1], [Enable debugging])], + [LIBXO_DEBUG=no]) +AC_MSG_RESULT([$LIBXO_DEBUG]) +AM_CONDITIONAL([LIBXO_DEBUG], [test "$LIBXO_DEBUG" != "no"]) + +AC_MSG_CHECKING([whether to use int return codes]) +AC_ARG_ENABLE([int-return-codes], + [ --enable-int-return-codes Use int return codes (instead of ssize_t)], + [USE_INT_RETURN_CODES=yes; AC_DEFINE([USE_INT_RETURN_CODES], [1], [Use int return codes])], + [USE_INT_RETURN_CODES=no]) +AC_MSG_RESULT([$USE_INT_RETURN_CODES]) + +AC_MSG_CHECKING([whether to build with text-only rendering]) +AC_ARG_ENABLE([text-only], + [ --enable-text-only Turn on text-only rendering], + [LIBXO_TEXT_ONLY=yes; AC_DEFINE([LIBXO_TEXT_ONLY], [1], [Enable text-only rendering])], + [LIBXO_TEXT_ONLY=no]) +AC_MSG_RESULT([$LIBXO_TEXT_ONLY]) +AM_CONDITIONAL([LIBXO_TEXT_ONLY], [test "$LIBXO_TEXT_ONLY" != "no"]) + +AC_MSG_CHECKING([whether to build with local wcwidth implementation]) +AC_ARG_ENABLE([wcwidth], + [ --disable-wcwidth Disable local wcwidth implementation], + [LIBXO_WCWIDTH=$enableval], + [LIBXO_WCWIDTH=yes]) +AC_MSG_RESULT([$LIBXO_WCWIDTH]) +if test "${LIBXO_WCWIDTH}" != "no"; then + AC_DEFINE([LIBXO_WCWIDTH], [1], [Enable local wcwidth implementation]) +fi + +AC_MSG_CHECKING([retain hash bucket size]) +AC_ARG_WITH(retain-size, + [ --with-retain-size=[DIR] Specify retain hash bucket size (in bits)], + [XO_RETAIN_SIZE=$withval], + [XO_RETAIN_SIZE=default] +) + +AC_MSG_RESULT([$XO_RETAIN_SIZE]) +if test "${XO_RETAIN_SIZE}" != "default"; then + AC_DEFINE_UNQUOTED([XO_RETAIN_SIZE], ${XO_RETAIN_SIZE}, [Retain hash bucket size]) +fi + +AC_CHECK_LIB([m], [lrint]) +AM_CONDITIONAL([HAVE_LIBM], [test "$HAVE_LIBM" != "no"]) + +AC_MSG_CHECKING([compiler for gcc]) +HAVE_GCC=no +if test "${CC}" != ""; then + HAVE_GCC=`${CC} --version 2>&1 | grep GCC` + if test "${HAVE_GCC}" != ""; then + HAVE_GCC=yes + else + HAVE_GCC=no + fi +fi +AC_MSG_RESULT([$HAVE_GCC]) +AM_CONDITIONAL([HAVE_GCC], [test "$HAVE_GCC" = "yes"]) + +AC_MSG_CHECKING([whether to build with printflike]) +AC_ARG_ENABLE([printflike], + [ --enable-printflike Enable use of GCC __printflike attribute], + [HAVE_PRINTFLIKE=yes; + AC_DEFINE([HAVE_PRINTFLIKE], [1], [Support printflike])], + [HAVE_PRINTFLIKE=no]) +AC_MSG_RESULT([$HAVE_PRINTFLIKE]) +AM_CONDITIONAL([HAVE_PRINTFLIKE], [test "$HAVE_PRINTFLIKE" != ""]) + +AC_MSG_CHECKING([whether to build with LIBXO_OPTIONS]) +AC_ARG_ENABLE([libxo-options], + [ --disable-libxo-options Turn off support for LIBXO_OPTIONS], + [LIBXO_OPTS=$enableval], + [LIBXO_OPTS=yes]) +AC_MSG_RESULT([$LIBXO_OPTS]) +AM_CONDITIONAL([NO_LIBXO_OPTIONS], [test "$LIBXO_OPTS" != "yes"]) + +case $host_os in + darwin*) + LIBTOOL=glibtool + XO_LIBEXT=dylib + ;; + Linux*|linux*) + CFLAGS="-D_GNU_SOURCE $CFLAGS" + LDFLAGS=-ldl + XO_LIBEXT=so + ;; + cygwin*|CYGWIN*) + LDFLAGS=-no-undefined + XO_LIBEXT=ddl + ;; +esac + +case $prefix in + NONE) + prefix=/usr/local + ;; +esac + +XO_LIBS=-lxo +XO_SRCDIR=${srcdir} +XO_LIBDIR=${libdir} +XO_BINDIR=${bindir} +XO_INCLUDEDIR=${includedir} +XO_CFLAGS="${CFLAGS}" + +AC_SUBST(XO_LIBS) +AC_SUBST(XO_SRCDIR) +AC_SUBST(XO_LIBDIR) +AC_SUBST(XO_BINDIR) +AC_SUBST(XO_INCLUDEDIR) +AC_SUBST(XO_LIBEXT) +AC_SUBST(XO_CFLAGS) + +AC_ARG_WITH(encoder-dir, + [ --with-encoder-dir=[DIR] Specify location of encoder libraries], + [XO_ENCODERDIR=$withval], + [XO_ENCODERDIR=$libdir/libxo/encoder] +) +AC_SUBST(XO_ENCODERDIR) + +AC_ARG_WITH(share-dir, + [ --with-share-dir=[DIR] Specify location of shared files], + [XO_SHAREDIR=$withval], + [XO_SHAREDIR=$datarootdir/libxo] +) +XO_SHAREDIR=`echo $XO_SHAREDIR | sed "s;\\${prefix};$prefix;"` +AC_SUBST(XO_SHAREDIR) + +dnl for the spec file +RELDATE=`date +'%Y-%m-%d%n'` +AC_SUBST(RELDATE) + +AC_MSG_RESULT(Using configure dir $ac_abs_confdir) + +if test -d $ac_abs_confdir/.git ; then + extra=`git branch | awk '/\*/ { print $2 }'` + if test "$extra" != "" -a "$extra" != "master" + then + LIBXO_VERSION_EXTRA="-git-$extra" + fi +fi + +LIBXO_VERSION=$PACKAGE_VERSION +LIBXO_VERSION_NUMBER=VERSION_TO_NUMBER(echo $PACKAGE_VERSION) +AC_SUBST(LIBXO_VERSION) +AC_SUBST(LIBXO_VERSION_NUMBER) +AC_SUBST(LIBXO_VERSION_EXTRA) + +AC_DEFINE_UNQUOTED(LIBXO_VERSION, ["$LIBXO_VERSION"], + [Version number as dotted value]) +AC_DEFINE_UNQUOTED(LIBXO_VERSION_NUMBER, [$LIBXO_VERSION_NUMBER], + [Version number as a number]) +AC_DEFINE_UNQUOTED(LIBXO_VERSION_STRING, ["$LIBXO_VERSION_NUMBER"], + [Version number as string]) +AC_DEFINE_UNQUOTED(LIBXO_VERSION_EXTRA, ["$LIBXO_VERSION_EXTRA"], + [Version number extra information]) + +AC_CONFIG_HEADERS([libxo/xo_config.h]) +AC_CONFIG_FILES([ + Makefile + libxo-config + xohtml/xohtml.sh + libxo/Makefile + libxo/add.man + encoder/Makefile + encoder/cbor/Makefile + encoder/csv/Makefile + encoder/test/Makefile + xo/Makefile + xolint/Makefile + xohtml/Makefile + xopo/Makefile + packaging/libxo.pc + doc/Makefile + doc/top-link.html + tests/Makefile + tests/core/Makefile + tests/gettext/Makefile + tests/xo/Makefile + packaging/libxo.spec + packaging/libxo.rb.base +]) +AC_OUTPUT + +AC_MSG_NOTICE([summary of build options: + + libxo version: ${VERSION} ${LIBXO_VERSION_EXTRA} + host type: ${host} / ${host_os} + install prefix: ${prefix} + srcdir: ${XO_SRCDIR} + libdir: ${XO_LIBDIR} + bindir: ${XO_BINDIR} + includedir: ${XO_INCLUDEDIR} + share dir: ${XO_SHAREDIR} + extensions dir: ${XO_ENCODERDIR} + oxtradoc dir: ${SLAX_OXTRADOCDIR} + + compiler: ${CC} (${HAVE_GCC:-no}) + compiler flags: ${CFLAGS} + library types: Shared=${enable_shared}, Static=${enable_static} + + warnings: ${LIBXO_WARNINGS:-no} + debug: ${LIBXO_DEBUG:-no} + printf-like: ${HAVE_PRINTFLIKE:-no} + libxo-options: ${LIBXO_OPTS:-no} + text-only: ${LIBXO_TEXT_ONLY:-no} + gettext: ${HAVE_GETTEXT:-no} (${GETTEXT_PREFIX}) + isthreaded: ${HAVE_ISTHREADED:-no} + thread-local: ${THREAD_LOCAL:-no} + local wcwidth: ${LIBXO_WCWIDTH:-no} + retain size: ${XO_RETAIN_SIZE:-no} +]) diff --git a/tools/libxo/doc/Makefile.am b/tools/libxo/doc/Makefile.am new file mode 100644 index 000000000..eb9ce3646 --- /dev/null +++ b/tools/libxo/doc/Makefile.am @@ -0,0 +1,29 @@ +# +# $Id$ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +doc docs: xolint.rst html + +# +# The contents of xolint.rst is generated based on xolint.pl, since we +# really want this to be self-documenting. But readthedocs.org needs this +# data to be _in_ repo. So we generate this file on command only, and +# the developer needs to commit any changes. +# + +xolint.rst: ${top_srcdir}/xolint/xolint.pl + perl ${top_srcdir}/xolint/xolint.pl -D > ${top_srcdir}/doc/xolint.rst + +SPHINX = python3 -msphinx + +html sphinx sphinx-html: + ${SPHINX} -M html ${srcdir} . -N -E + +singlehtml: + ${SPHINX} -M singlehtml ${srcdir} . -N -E diff --git a/tools/libxo/doc/_static/basic.css_t b/tools/libxo/doc/_static/basic.css_t new file mode 100644 index 000000000..e8ebdc780 --- /dev/null +++ b/tools/libxo/doc/_static/basic.css_t @@ -0,0 +1,657 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: {{ theme_sidebarwidth|toint }}px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +blockquote.epigraph p.attribution { + margin-left: 50%; +} + +blockquote.epigraph { + background-color: #eee; + padding: 0.5em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { +/* clear: right; */ + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 1em 1em 1em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +dl.function table.docutils th.field-name { + width: 100px; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 1px solid #aaa; + border-left: 1px solid #aaa; + border-right: 1px solid #aaa; + border-bottom: 1px solid #aaa; +} + +table.docutils th { + border-bottom: 2px solid #aaa; + background-color: #f2f2f2; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +div.code-block-caption { + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +div.code-block-caption + div > div.highlight > pre { + margin-top: 0; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + padding: 1em 1em 0; +} + +div.literal-block-wrapper div.highlight { + margin: 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: relative; + left: 0px; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} diff --git a/tools/libxo/doc/_templates/localtoc.html b/tools/libxo/doc/_templates/localtoc.html new file mode 100644 index 000000000..14fdb12a5 --- /dev/null +++ b/tools/libxo/doc/_templates/localtoc.html @@ -0,0 +1,14 @@ +{# + basic/localtoc.html + ~~~~~~~~~~~~~~~~~~~ + + Sphinx sidebar template: local table of contents. + + :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- if display_toc %} +

{{ _('On This Page') }}

+ {{ toc }} +

{{ _('Full Documentation') }}

+{%- endif %} diff --git a/tools/libxo/doc/api.rst b/tools/libxo/doc/api.rst new file mode 100644 index 000000000..94358489f --- /dev/null +++ b/tools/libxo/doc/api.rst @@ -0,0 +1,1679 @@ +.. index:: API + +The libxo API +============= + +This section gives details about the functions in libxo, how to call +them, and the actions they perform. + +.. index:: Handles +.. _handles: + +Handles +------- + +libxo uses "handles" to control its rendering functionality. The +handle contains state and buffered data, as well as callback functions +to process data. + +Handles give an abstraction for libxo that encapsulates the state of a +stream of output. Handles have the data type "`xo_handle_t`" and are +opaque to the caller. + +The library has a default handle that is automatically initialized. +By default, this handle will send text style output (`XO_STYLE_TEXT`) to +standard output. The xo_set_style and xo_set_flags functions can be +used to change this behavior. + +For the typical command that is generating output on standard output, +there is no need to create an explicit handle, but they are available +when needed, e.g., for daemons that generate multiple streams of +output. + +Many libxo functions take a handle as their first parameter; most that +do not use the default handle. Any function taking a handle can be +passed NULL to access the default handle. For the convenience of +callers, the libxo library includes handle-less functions that +implicitly use the default handle. + +For example, the following are equivalent:: + + xo_emit("test"); + xo_emit_h(NULL, "test"); + +Handles are created using `xo_create` and destroy using +`xo_destroy`. + +.. index:: xo_create + +xo_create +~~~~~~~~~ + +.. c:function:: xo_handle_t *xo_create (xo_style_t style, xo_xof_flags_t flags) + + The `xo_create` function allocates a new handle which can be passed + to further libxo function calls. The `xo_handle_t` structure is + opaque. + + :param xo_style_t style: Output style (XO_STYLE\_*) + :param xo_xof_flags_t flags: Flags for this handle (XOF\_*) + :return: New libxo handle + :rtype: xo_handle_t \* + + :: + + EXAMPLE: + xo_handle_t *xop = xo_create(XO_STYLE_JSON, XOF_WARN | XOF_PRETTY); + .... + xo_emit_h(xop, "testing\n"); + + See also :ref:`output-styles` and :ref:`flags`. + +.. index:: xo_create_to_file +.. index:: XOF_CLOSE_FP + +xo_create_to_file +~~~~~~~~~~~~~~~~~ + +.. c:function:: + xo_handle_t *xo_create_to_file (FILE *fp, unsigned style, unsigned flags) + + The `xo_create_to_file` function is aconvenience function is + provided for situations when output should be written to a different + file, rather than the default of standard output. + + The `XOF_CLOSE_FP` flag can be set on the returned handle to trigger a + call to fclose() for the FILE pointer when the handle is destroyed, + avoiding the need for the caller to perform this task. + + :param fp: FILE to use as base for this handle + :type fp: FILE * + :param xo_style_t style: Output style (XO_STYLE\_*) + :param xo_xof_flags_t flags: Flags for this handle (XOF\_*) + :return: New libxo handle + :rtype: xo_handle_t \* + +.. index:: xo_set_writer +.. index:: xo_write_func_t +.. index:: xo_close_func_t +.. index:: xo_flush_func_t + +xo_set_writer +~~~~~~~~~~~~~ + +.. c:function:: + void xo_set_writer (xo_handle_t *xop, void *opaque, \ + xo_write_func_t write_func, xo_close_func_t close_func, \ + xo_flush_func_t flush_func) + + The `xo_set_writer` function allows custom functions which can + tailor how libxo writes data. The `opaque` argument is recorded and + passed back to the functions, allowing the function to acquire + context information. The *write_func* function writes data to the + output stream. The *close_func* function can release this opaque + data and any other resources as needed. The *flush_func* function + is called to flush buffered data associated with the opaque object. + + :param xop: Handle to modify (or NULL for default handle) + :type xop: xo_handle_t * + :param opaque: Pointer to opaque data passed to the given functions + :type opaque: void * + :param xo_write_func_t write_func: New write function + :param xo_close_func_t close_func: New close function + :param xo_flush_func_t flush_func: New flush function + :returns: void + +.. index:: xo_get_style + +xo_get_style +~~~~~~~~~~~~ + +.. c:function:: xo_style_t xo_get_style(xo_handle_t *xop) + + Use the `xo_get_style` function to find the current output style for + a given handle. To use the default handle, pass a `NULL` handle. + + :param xop: Handle to interrogate (or NULL for default handle) + :type xop: xo_handle_t * + :returns: Output style (XO_STYLE\_*) + :rtype: xo_style_t + + :: + + EXAMPLE:: + style = xo_get_style(NULL); + +.. index:: XO_STYLE_TEXT +.. index:: XO_STYLE_XML +.. index:: XO_STYLE_JSON +.. index:: XO_STYLE_HTML + +.. _output-styles: + +Output Styles (XO_STYLE\_\*) +++++++++++++++++++++++++++++ + +The libxo functions accept a set of output styles: + + =============== ========================= + Flag Description + =============== ========================= + XO_STYLE_TEXT Traditional text output + XO_STYLE_XML XML encoded data + XO_STYLE_JSON JSON encoded data + XO_STYLE_HTML HTML encoded data + =============== ========================= + +The "XML", "JSON", and "HTML" output styles all use the UTF-8 +character encoding. "TEXT" using locale-based encoding. + +.. index:: xo_set_style + +xo_set_style +~~~~~~~~~~~~ + +.. c:function:: void xo_set_style(xo_handle_t *xop, xo_style_t style) + + The `xo_set_style` function is used to change the output style + setting for a handle. To use the default handle, pass a `NULL` + handle. + + :param xop: Handle to modify + :type xop: xo_handle_t * + :param xo_style_t style: Output style (XO_STYLE\_*) + :returns: void + + :: + + EXAMPLE: + xo_set_style(NULL, XO_STYLE_XML); + +.. index:: xo_set_style_name + +xo_set_style_name +~~~~~~~~~~~~~~~~~ + +.. c:function:: int xo_set_style_name (xo_handle_t *xop, const char *style) + + The `xo_set_style_name` function can be used to set the style based + on a name encoded as a string: The name can be any of the supported + styles: "text", "xml", "json", or "html". + + :param xop: Handle for modify (or NULL for default handle) + :type xop: xo_handle_t \* + :param style: Text name of the style + :type style: const char \* + :returns: zero for success, non-zero for error + :rtype: int + + :: + + EXAMPLE: + xo_set_style_name(NULL, "html"); + +.. index:: xo_set_flags + +xo_set_flags +~~~~~~~~~~~~ + +.. c:function:: void xo_set_flags(xo_handle_t *xop, xo_xof_flags_t flags) + + :param xop: Handle for modify (or NULL for default handle) + :type xop: xo_handle_t \* + :param xo_xof_flags_t flags: Flags to add for the handle + :returns: void + + Use the `xo_set_flags` function to turn on flags for a given libxo + handle. To use the default handle, pass a `NULL` handle. + + :: + + EXAMPLE: + xo_set_flags(NULL, XOF_PRETTY | XOF_WARN); + +.. index:: Flags; XOF_* +.. index:: XOF_CLOSE_FP +.. index:: XOF_COLOR +.. index:: XOF_COLOR_ALLOWED +.. index:: XOF_DTRT +.. index:: XOF_INFO +.. index:: XOF_KEYS +.. index:: XOF_NO_ENV +.. index:: XOF_NO_HUMANIZE +.. index:: XOF_PRETTY +.. index:: XOF_UNDERSCORES +.. index:: XOF_UNITS +.. index:: XOF_WARN +.. index:: XOF_WARN_XML +.. index:: XOF_XPATH +.. index:: XOF_COLUMNS +.. index:: XOF_FLUSH + +.. _flags: + +Flags (XOF\_\*) ++++++++++++++++ + +The set of valid flags include: + + =================== ========================================= + Flag Description + =================== ========================================= + XOF_CLOSE_FP Close file pointer on `xo_destroy` + XOF_COLOR Enable color and effects in output + XOF_COLOR_ALLOWED Allow color/effect for terminal output + XOF_DTRT Enable "do the right thing" mode + XOF_INFO Display info data attributes (HTML) + XOF_KEYS Emit the key attribute (XML) + XOF_NO_ENV Do not use the :ref:`libxo-options` env var + XOF_NO_HUMANIZE Display humanization (TEXT, HTML) + XOF_PRETTY Make "pretty printed" output + XOF_UNDERSCORES Replaces hyphens with underscores + XOF_UNITS Display units (XML, HMTL) + XOF_WARN Generate warnings for broken calls + XOF_WARN_XML Generate warnings in XML on stdout + XOF_XPATH Emit XPath expressions (HTML) + XOF_COLUMNS Force xo_emit to return columns used + XOF_FLUSH Flush output after each `xo_emit` call + =================== ========================================= + +The `XOF_CLOSE_FP` flag will trigger the call of the *close_func* +(provided via `xo_set_writer`) when the handle is destroyed. + +The `XOF_COLOR` flag enables color and effects in output regardless +of output device, while the `XOF_COLOR_ALLOWED` flag allows color +and effects only if the output device is a terminal. + +The `XOF_PRETTY` flag requests "pretty printing", which will trigger +the addition of indentation and newlines to enhance the readability of +XML, JSON, and HTML output. Text output is not affected. + +The `XOF_WARN` flag requests that warnings will trigger diagnostic +output (on standard error) when the library notices errors during +operations, or with arguments to functions. Without warnings enabled, +such conditions are ignored. + +Warnings allow developers to debug their interaction with libxo. +The function `xo_failure` can used as a breakpoint for a debugger, +regardless of whether warnings are enabled. + +If the style is `XO_STYLE_HTML`, the following additional flags can be +used: + + =============== ========================================= + Flag Description + =============== ========================================= + XOF_XPATH Emit "data-xpath" attributes + XOF_INFO Emit additional info fields + =============== ========================================= + +The `XOF_XPATH` flag enables the emission of XPath expressions detailing +the hierarchy of XML elements used to encode the data field, if the +XPATH style of output were requested. + +The `XOF_INFO` flag encodes additional informational fields for HTML +output. See :ref:`field-information` for details. + +If the style is `XO_STYLE_XML`, the following additional flags can be +used: + + =============== ========================================= + Flag Description + =============== ========================================= + XOF_KEYS Flag "key" fields for XML + =============== ========================================= + +The `XOF_KEYS` flag adds "key" attribute to the XML encoding for +field definitions that use the "k" modifier. The key attribute has +the value "key":: + + xo_emit("{k:name}", item); + + XML: + truck + +.. index:: xo_clear_flags + +xo_clear_flags +++++++++++++++ + +.. c:function:: void xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags) + + :param xop: Handle for modify (or NULL for default handle) + :type xop: xo_handle_t \* + :param xo_xof_flags_t flags: Flags to clear for the handle + :returns: void + + Use the `xo_clear_flags` function to turn off the given flags in a + specific handle. To use the default handle, pass a `NULL` handle. + +.. index:: xo_set_options + +xo_set_options +++++++++++++++ + +.. c:function:: int xo_set_options (xo_handle_t *xop, const char *input) + + :param xop: Handle for modify (or NULL for default handle) + :type xop: xo_handle_t \* + :param input: string containing options to set + :type input: const char * + :returns: zero for success, non-zero for error + :rtype: int + + The `xo_set_options` function accepts a comma-separated list of + output styles and modifier flags and enables them for a specific + handle. The options are identical to those listed in + :ref:`options`. To use the default handle, pass a `NULL` handle. + +.. index:: xo_destroy + +xo_destroy +++++++++++ + +.. c:function:: void xo_destroy(xo_handle_t *xop) + + :param xop: Handle for modify (or NULL for default handle) + :type xop: xo_handle_t \* + :returns: void + + The `xo_destroy` function releases a handle and any resources it is + using. Calling `xo_destroy` with a `NULL` handle will release any + resources associated with the default handle. + +.. index:: xo_emit + +Emitting Content (xo_emit) +-------------------------- + +The functions in this section are used to emit output. + +The "fmt" argument is a string containing field descriptors as +specified in :ref:`format-strings`. The use of a handle is optional and +`NULL` can be passed to access the internal "default" handle. See +:ref:`handles`. + +The remaining arguments to `xo_emit` and `xo_emit_h` are a set of +arguments corresponding to the fields in the format string. Care must +be taken to ensure the argument types match the fields in the format +string, since an inappropriate cast can ruin your day. The vap +argument to `xo_emit_hv` points to a variable argument list that can +be used to retrieve arguments via `va_arg`. + +.. c:function:: xo_ssize_t xo_emit (const char *fmt, ...) + + :param fmt: The format string, followed by zero or more arguments + :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted + :rtype: xo_ssize_t + +.. c:function:: xo_ssize_t xo_emit_h (xo_handle_t *xop, const char *fmt, ...) + + :param xop: Handle for modify (or NULL for default handle) + :type xop: xo_handle_t \* + :param fmt: The format string, followed by zero or more arguments + :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted + :rtype: xo_ssize_t + +.. c:function:: xo_ssize_t xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap) + + :param xop: Handle for modify (or NULL for default handle) + :type xop: xo_handle_t \* + :param fmt: The format string + :param va_list vap: A set of variadic arguments + :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted + :rtype: xo_ssize_t + +.. index:: xo_emit_field + +Single Field Emitting Functions (xo_emit_field) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The functions in this section can also make output, but only make a +single field at a time. These functions are intended to avoid the +scenario where one would otherwise need to compose a format +descriptors using `snprintf`. The individual parts of the format +descriptor are passed in distinctly. + +.. c:function:: xo_ssize_t xo_emit_field (const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...) + + :param rolmod: A comma-separated list of field roles and field modifiers + :type rolmod: const char * + :param contents: The "contents" portion of the field description string + :type contents: const char * + :param fmt: Content format string + :type fmt: const char * + :param efmt: Encoding format string, followed by additional arguments + :type efmt: const char * + :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted + :rtype: xo_ssize_t + + :: + + EXAMPLE:: + xo_emit_field("T", "Host name is ", NULL, NULL); + xo_emit_field("V", "host-name", NULL, NULL, host-name); + +.. c:function:: xo_ssize_t xo_emit_field_h (xo_handle_t *xop, const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...) + + :param xop: Handle for modify (or NULL for default handle) + :type xop: xo_handle_t \* + :param rolmod: A comma-separated list of field roles and field modifiers + :type rolmod: const char * + :param contents: The "contents" portion of the field description string + :type contents: const char * + :param fmt: Content format string + :type fmt: const char * + :param efmt: Encoding format string, followed by additional arguments + :type efmt: const char * + :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted + :rtype: xo_ssize_t + +.. c:function:: xo_ssize_t xo_emit_field_hv (xo_handle_t *xop, const char *rolmod, const char *contents, const char *fmt, const char *efmt, va_list vap) + + :param xop: Handle for modify (or NULL for default handle) + :type xop: xo_handle_t \* + :param rolmod: A comma-separated list of field roles and field modifiers + :type rolmod: const char * + :param contents: The "contents" portion of the field description string + :type contents: const char * + :param fmt: Content format string + :type fmt: const char * + :param efmt: Encoding format string + :type efmt: const char * + :param va_list vap: A set of variadic arguments + :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted + :rtype: xo_ssize_t + +.. index:: xo_attr +.. _xo_attr: + +Attributes (xo_attr) +~~~~~~~~~~~~~~~~~~~~ + +The functions in this section emit an XML attribute with the given name +and value. This only affects the XML output style. + +The `name` parameter give the name of the attribute to be encoded. The +`fmt` parameter gives a printf-style format string used to format the +value of the attribute using any remaining arguments, or the vap +parameter passed to `xo_attr_hv`. + +All attributes recorded via `xo_attr` are placed on the next +container, instance, leaf, or leaf list that is emitted. + +Since attributes are only emitted in XML, their use should be limited +to meta-data and additional or redundant representations of data +already emitted in other form. + +.. c:function:: xo_ssize_t xo_attr (const char *name, const char *fmt, ...) + + :param name: Attribute name + :type name: const char * + :param fmt: Attribute value, as variadic arguments + :type fmt: const char * + :returns: -1 for error, or the number of bytes in the formatted attribute value + :rtype: xo_ssize_t + + :: + + EXAMPLE: + xo_attr("seconds", "%ld", (unsigned long) login_time); + struct tm *tmp = localtime(login_time); + strftime(buf, sizeof(buf), "%R", tmp); + xo_emit("Logged in at {:login-time}\n", buf); + XML: + 00:14 + + +.. c:function:: xo_ssize_t xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...) + + :param xop: Handle for modify (or NULL for default handle) + :type xop: xo_handle_t \* + + The `xo_attr_h` function follows the conventions of `xo_attr` but + adds an explicit libxo handle. + +.. c:function:: xo_ssize_t xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap) + + The `xo_attr_h` function follows the conventions of `xo_attr_h` + but replaced the variadic list with a variadic pointer. + +.. index:: xo_flush + +Flushing Output (xo_flush) +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. c:function:: xo_ssize_t xo_flush (void) + + :returns: -1 for error, or the number of bytes generated + :rtype: xo_ssize_t + + libxo buffers data, both for performance and consistency, but also + to allow for the proper function of various advanced features. At + various times, the caller may wish to flush any data buffered within + the library. The `xo_flush` call is used for this. + + Calling `xo_flush` also triggers the flush function associated with + the handle. For the default handle, this is equivalent to + "fflush(stdio);". + +.. c:function:: xo_ssize_t xo_flush_h (xo_handle_t *xop) + + :param xop: Handle for flush (or NULL for default handle) + :type xop: xo_handle_t \* + :returns: -1 for error, or the number of bytes generated + :rtype: xo_ssize_t + + The `xo_flush_h` function follows the conventions of `xo_flush`, + but adds an explicit libxo handle. + +.. index:: xo_finish +.. index:: xo_finish_atexit +.. index:: atexit + +Finishing Output (xo_finish) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When the program is ready to exit or close a handle, a call to +`xo_finish` or `xo_finish_h` is required. This flushes any buffered +data, closes open libxo constructs, and completes any pending +operations. + +Calling this function is vital to the proper operation of libxo, +especially for the non-TEXT output styles. + +.. c:function:: xo_ssize_t xo_finish (void) + + :returns: -1 on error, or the number of bytes flushed + :rtype: xo_ssize_t + +.. c:function:: xo_ssize_t xo_finish_h (xo_handle_t *xop) + + :param xop: Handle for finish (or NULL for default handle) + :type xop: xo_handle_t \* + :returns: -1 on error, or the number of bytes flushed + :rtype: xo_ssize_t + +.. c:function:: void xo_finish_atexit (void) + + The `xo_finish_atexit` function is suitable for use with + :manpage:`atexit(3)` to ensure that `xo_finish` is called + on the default handle when the application exits. + +.. index:: UTF-8 +.. index:: xo_open_container +.. index:: xo_close_container + +Emitting Hierarchy +------------------ + +libxo represents two types of hierarchy: containers and lists. A +container appears once under a given parent where a list consists of +instances that can appear multiple times. A container is used to hold +related fields and to give the data organization and scope. + +.. index:: YANG + +.. admonition:: YANG Terminology + + libxo uses terminology from YANG (:RFC:`7950`), the data modeling + language for NETCONF: container, list, leaf, and leaf-list. + +For XML and JSON, individual fields appear inside hierarchies which +provide context and meaning to the fields. Unfortunately, these +encoding have a basic disconnect between how lists is similar objects +are represented. + +XML encodes lists as set of sequential elements:: + + phil + pallavi + sjg + +JSON encodes lists using a single name and square brackets:: + + "user": [ "phil", "pallavi", "sjg" ] + +This means libxo needs three distinct indications of hierarchy: one +for containers of hierarchy appear only once for any specific parent, +one for lists, and one for each item in a list. + +.. index:: Containers + +Containers +~~~~~~~~~~ + +A "*container*" is an element of a hierarchy that appears only once +under any specific parent. The container has no value, but serves to +contain and organize other nodes. + +To open a container, call xo_open_container() or +xo_open_container_h(). The former uses the default handle and the +latter accepts a specific handle. To close a level, use the +xo_close_container() or xo_close_container_h() functions. + +Each open call must have a matching close call. If the XOF_WARN flag +is set and the name given does not match the name of the currently open +container, a warning will be generated. + +.. c:function:: xo_ssize_t xo_open_container (const char *name) + + :param name: Name of the container + :type name: const char * + :returns: -1 on error, or the number of bytes generated + :rtype: xo_ssize_t + + The `name` parameter gives the name of the container, encoded in + UTF-8. Since ASCII is a proper subset of UTF-8, traditional C + strings can be used directly. + +.. c:function:: xo_ssize_t xo_open_container_h (xo_handle_t *xop, const char *name) + + :param xop: Handle to use (or NULL for default handle) + :type xop: xo_handle_t * + + The `xo_open_container_h` function adds a `handle` parameter. + +.. c:function:: xo_ssize_t xo_close_container (const char *name) + + :param name: Name of the container + :type name: const char * + :returns: -1 on error, or the number of bytes generated + :rtype: xo_ssize_t + +.. c:function:: xo_ssize_t xo_close_container_h (xo_handle_t *xop, const char *name) + + :param xop: Handle to use (or NULL for default handle) + :type xop: xo_handle_t * + + The `xo_close_container_h` function adds a `handle` parameter. + +Use the :index:`XOF_WARN` flag to generate a warning if the name given +on the close does not match the current open container. + +For TEXT and HTML output, containers are not rendered into output +text, though for HTML they are used to record an XPath value when the +:index:`XOF_XPATH` flag is set. + +:: + + EXAMPLE: + xo_open_container("top"); + xo_open_container("system"); + xo_emit("{:host-name/%s%s%s}", hostname, + domainname ? "." : "", domainname ?: ""); + xo_close_container("system"); + xo_close_container("top"); + TEXT: + my-host.example.org + XML: + + + my-host.example.org + + + JSON: + "top" : { + "system" : { + "host-name": "my-host.example.org" + } + } + HTML: +
my-host.example.org
+ +.. index:: xo_open_instance +.. index:: xo_close_instance +.. index:: xo_open_list +.. index:: xo_close_list + +Lists and Instances +~~~~~~~~~~~~~~~~~~~ + +A "*list*" is set of one or more instances that appear under the same +parent. The instances contain details about a specific object. One +can think of instances as objects or records. A call is needed to +open and close the list, while a distinct call is needed to open and +close each instance of the list. + +The name given to all calls must be identical, and it is strongly +suggested that the name be singular, not plural, as a matter of +style and usage expectations:: + + EXAMPLE: + xo_open_list("item"); + + for (ip = list; ip->i_title; ip++) { + xo_open_instance("item"); + xo_emit("{L:Item} '{:name/%s}':\n", ip->i_title); + xo_close_instance("item"); + } + + xo_close_list("item"); + +Getting the list and instance calls correct is critical to the proper +generation of XML and JSON data. + +Opening Lists ++++++++++++++ + +.. c:function:: xo_ssize_t xo_open_list (const char *name) + + :param name: Name of the list + :type name: const char * + :returns: -1 on error, or the number of bytes generated + :rtype: xo_ssize_t + + The `xo_open_list` function open a list of instances. + +.. c:function:: xo_ssize_t xo_open_list_h (xo_handle_t *xop, const char *name) + + :param xop: Handle to use (or NULL for default handle) + :type xop: xo_handle_t * + +Closing Lists ++++++++++++++ + +.. c:function:: xo_ssize_t xo_close_list (const char *name) + + :param name: Name of the list + :type name: const char * + :returns: -1 on error, or the number of bytes generated + :rtype: xo_ssize_t + + The `xo_close_list` function closes a list of instances. + +.. c:function:: xo_ssize_t xo_close_list_h (xo_handle_t *xop, const char *name) + + :param xop: Handle to use (or NULL for default handle) + :type xop: xo_handle_t * + + The `xo_close_container_h` function adds a `handle` parameter. + +Opening Instances ++++++++++++++++++ + +.. c:function:: xo_ssize_t xo_open_instance (const char *name) + + :param name: Name of the instance (same as the list name) + :type name: const char * + :returns: -1 on error, or the number of bytes generated + :rtype: xo_ssize_t + + The `xo_open_instance` function open a single instance. + +.. c:function:: xo_ssize_t xo_open_instance_h (xo_handle_t *xop, const char *name) + + :param xop: Handle to use (or NULL for default handle) + :type xop: xo_handle_t * + + The `xo_open_instance_h` function adds a `handle` parameter. + +Closing Instances ++++++++++++++++++ + +.. c:function:: xo_ssize_t xo_close_instance (const char *name) + + :param name: Name of the instance + :type name: const char * + :returns: -1 on error, or the number of bytes generated + :rtype: xo_ssize_t + + The `xo_close_instance` function closes an open instance. + +.. c:function:: xo_ssize_t xo_close_instance_h (xo_handle_t *xop, const char *name) + + :param xop: Handle to use (or NULL for default handle) + :type xop: xo_handle_t * + + The `xo_close_instance_h` function adds a `handle` parameter. + + :: + + EXAMPLE: + xo_open_list("user"); + for (i = 0; i < num_users; i++) { + xo_open_instance("user"); + xo_emit("{k:name}:{:uid/%u}:{:gid/%u}:{:home}\n", + pw[i].pw_name, pw[i].pw_uid, + pw[i].pw_gid, pw[i].pw_dir); + xo_close_instance("user"); + } + xo_close_list("user"); + TEXT: + phil:1001:1001:/home/phil + pallavi:1002:1002:/home/pallavi + XML: + + phil + 1001 + 1001 + /home/phil + + + pallavi + 1002 + 1002 + /home/pallavi + + JSON: + user: [ + { + "name": "phil", + "uid": 1001, + "gid": 1001, + "home": "/home/phil", + }, + { + "name": "pallavi", + "uid": 1002, + "gid": 1002, + "home": "/home/pallavi", + } + ] + +Markers +~~~~~~~ + +Markers are used to protect and restore the state of open hierarchy +constructs (containers, lists, or instances). While a marker is open, +no other open constructs can be closed. When a marker is closed, all +constructs open since the marker was opened will be closed. + +Markers use names which are not user-visible, allowing the caller to +choose appropriate internal names. + +In this example, the code whiffles through a list of fish, calling a +function to emit details about each fish. The marker "fish-guts" is +used to ensure that any constructs opened by the function are closed +properly:: + + EXAMPLE: + for (i = 0; fish[i]; i++) { + xo_open_instance("fish"); + xo_open_marker("fish-guts"); + dump_fish_details(i); + xo_close_marker("fish-guts"); + } + +.. c:function:: xo_ssize_t xo_open_marker(const char *name) + + :param name: Name of the instance + :type name: const char * + :returns: -1 on error, or the number of bytes generated + :rtype: xo_ssize_t + + The `xo_open_marker` function records the current state of open tags + in order for `xo_close_marker` to close them at some later point. + +.. c:function:: xo_ssize_t xo_open_marker_h(const char *name) + + :param xop: Handle to use (or NULL for default handle) + :type xop: xo_handle_t * + + The `xo_open_marker_h` function adds a `handle` parameter. + +.. c:function:: xo_ssize_t xo_close_marker(const char *name) + + :param name: Name of the instance + :type name: const char * + :returns: -1 on error, or the number of bytes generated + :rtype: xo_ssize_t + + The `xo_close_marker` function closes any open containers, lists, or + instances as needed to return to the state recorded when + `xo_open_marker` was called with the matching name. + +.. c:function:: xo_ssize_t xo_close_marker(const char *name) + + :param xop: Handle to use (or NULL for default handle) + :type xop: xo_handle_t * + + The `xo_close_marker_h` function adds a `handle` parameter. + +DTRT Mode +~~~~~~~~~ + +Some users may find tracking the names of open containers, lists, and +instances inconvenient. libxo offers a "Do The Right Thing" mode, where +libxo will track the names of open containers, lists, and instances so +the close function can be called without a name. To enable DTRT mode, +turn on the XOF_DTRT flag prior to making any other libxo output:: + + xo_set_flags(NULL, XOF_DTRT); + +.. index:: XOF_DTRT + +Each open and close function has a version with the suffix "_d", which +will close the open container, list, or instance:: + + xo_open_container_d("top"); + ... + xo_close_container_d(); + +This also works for lists and instances:: + + xo_open_list_d("item"); + for (...) { + xo_open_instance_d("item"); + xo_emit(...); + xo_close_instance_d(); + } + xo_close_list_d(); + +.. index:: XOF_WARN + +Note that the XOF_WARN flag will also cause libxo to track open +containers, lists, and instances. A warning is generated when the +name given to the close function and the name recorded do not match. + +Support Functions +----------------- + +.. index:: xo_parse_args +.. _xo_parse_args: + +Parsing Command-line Arguments (xo_parse_args) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. c:function:: int xo_parse_args (int argc, char **argv) + + :param int argc: Number of arguments + :param argv: Array of argument strings + :return: -1 on error, or the number of remaining arguments + :rtype: int + + The `xo_parse_args` function is used to process a program's + arguments. libxo-specific options are processed and removed from + the argument list so the calling application does not need to + process them. If successful, a new value for argc is returned. On + failure, a message is emitted and -1 is returned:: + + argc = xo_parse_args(argc, argv); + if (argc < 0) + exit(EXIT_FAILURE); + + Following the call to xo_parse_args, the application can process the + remaining arguments in a normal manner. See :ref:`options` for a + description of valid arguments. + +.. index:: xo_set_program + +xo_set_program +~~~~~~~~~~~~~~ + +.. c:function:: void xo_set_program (const char *name) + + :param name: Name to use as the program name + :type name: const char * + :returns: void + + The `xo_set_program` function sets the name of the program as + reported by functions like `xo_failure`, `xo_warn`, `xo_err`, etc. + The program name is initialized by `xo_parse_args`, but subsequent + calls to `xo_set_program` can override this value:: + + EXAMPLE: + xo_set_program(argv[0]); + + Note that the value is not copied, so the memory passed to + `xo_set_program` (and `xo_parse_args`) must be maintained by the + caller. + +.. index:: xo_set_version + +xo_set_version +~~~~~~~~~~~~~~ + +.. c:function:: void xo_set_version (const char *version) + + :param name: Value to use as the version string + :type name: const char * + :returns: void + + The `xo_set_version` function records a version number to be emitted + as part of the data for encoding styles (XML and JSON). This + version number is suitable for tracking changes in the content, + allowing a user of the data to discern which version of the data + model is in use. + +.. c:function:: void xo_set_version_h (xo_handle_t *xop, const char *version) + + :param xop: Handle to use (or NULL for default handle) + :type xop: xo_handle_t * + + The `xo_set_version` function adds a `handle` parameter. + +.. index:: --libxo +.. index:: XOF_INFO +.. index:: xo_info_t + +.. _field-information: + +Field Information (xo_info_t) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +HTML data can include additional information in attributes that +begin with "data-". To enable this, three things must occur: + +First the application must build an array of xo_info_t structures, +one per tag. The array must be sorted by name, since libxo uses a +binary search to find the entry that matches names from format +instructions. + +Second, the application must inform libxo about this information using +the `xo_set_info` call:: + + typedef struct xo_info_s { + const char *xi_name; /* Name of the element */ + const char *xi_type; /* Type of field */ + const char *xi_help; /* Description of field */ + } xo_info_t; + + void xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count); + +Like other libxo calls, passing `NULL` for the handle tells libxo to +use the default handle. + +If the count is -1, libxo will count the elements of infop, but there +must be an empty element at the end. More typically, the number is +known to the application:: + + xo_info_t info[] = { + { "in-stock", "number", "Number of items in stock" }, + { "name", "string", "Name of the item" }, + { "on-order", "number", "Number of items on order" }, + { "sku", "string", "Stock Keeping Unit" }, + { "sold", "number", "Number of items sold" }, + }; + int info_count = (sizeof(info) / sizeof(info[0])); + ... + xo_set_info(NULL, info, info_count); + +Third, the emission of info must be triggered with the `XOF_INFO` flag +using either the `xo_set_flags` function or the "`--libxo=info`" +command line argument. + +The type and help values, if present, are emitted as the "data-type" +and "data-help" attributes:: + +
GRO-000-533
+ +.. c:function:: void xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count) + + :param xop: Handle to use (or NULL for default handle) + :type xop: xo_handle_t * + :param infop: Array of information structures + :type infop: xo_info_t * + :returns: void + +.. index:: xo_set_allocator +.. index:: xo_realloc_func_t +.. index:: xo_free_func_t + +Memory Allocation +~~~~~~~~~~~~~~~~~ + +The `xo_set_allocator` function allows libxo to be used in +environments where the standard :manpage:`realloc(3)` and +:manpage:`free(3)` functions are not appropriate. + +.. c:function:: void xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func) + + :param xo_realloc_func_t realloc_func: Allocation function + :param xo_free_func_t free_func: Free function + + *realloc_func* should expect the same arguments as + :manpage:`realloc(3)` and return a pointer to memory following the + same convention. *free_func* will receive the same argument as + :manpage:`free(3)` and should release it, as appropriate for the + environment. + +By default, the standard :manpage:`realloc(3)` and :manpage:`free(3)` +functions are used. + +.. index:: --libxo + +.. _libxo-options: + +LIBXO_OPTIONS +~~~~~~~~~~~~~ + +The environment variable "LIBXO_OPTIONS" can be set to a subset of +libxo options, including: + +- color +- flush +- flush-line +- no-color +- no-humanize +- no-locale +- no-retain +- pretty +- retain +- underscores +- warn + +For example, warnings can be enabled by:: + + % env LIBXO_OPTIONS=warn my-app + +Since environment variables are inherited, child processes will have +the same options, which may be undesirable, making the use of the +"`--libxo`" command-line option preferable in most situations. + +.. index:: xo_warn +.. index:: xo_err +.. index:: xo_errx +.. index:: xo_message + +Errors, Warnings, and Messages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Many programs make use of the standard library functions +:manpage:`err(3)` and :manpage:`warn(3)` to generate errors and +warnings for the user. libxo wants to pass that information via the +current output style, and provides compatible functions to allow +this:: + + void xo_warn (const char *fmt, ...); + void xo_warnx (const char *fmt, ...); + void xo_warn_c (int code, const char *fmt, ...); + void xo_warn_hc (xo_handle_t *xop, int code, + const char *fmt, ...); + void xo_err (int eval, const char *fmt, ...); + void xo_errc (int eval, int code, const char *fmt, ...); + void xo_errx (int eval, const char *fmt, ...); + +:: + + void xo_message (const char *fmt, ...); + void xo_message_c (int code, const char *fmt, ...); + void xo_message_hc (xo_handle_t *xop, int code, + const char *fmt, ...); + void xo_message_hcv (xo_handle_t *xop, int code, + const char *fmt, va_list vap); + +These functions display the program name, a colon, a formatted message +based on the arguments, and then optionally a colon and an error +message associated with either *errno* or the *code* parameter:: + + EXAMPLE: + if (open(filename, O_RDONLY) < 0) + xo_err(1, "cannot open file '%s'", filename); + +.. index:: xo_error +.. index:: xo_error_h +.. index:: xo_error_hv +.. index:: xo_errorn +.. index:: xo_errorn_h +.. index:: xo_errorn_hv + +xo_error +~~~~~~~~ + +.. c:function:: void xo_error (const char *fmt, ...) + + :param fmt: Format string + :type fmt: const char * + :returns: void + +.. c:function:: void xo_error_h (xo_handle_t *xop, const char *fmt, ...) + + :param xop: libxo handle pointer + :type xop: xo_handle_t * + :param fmt: Format string + :type fmt: const char * + :returns: void + +.. c:function:: void xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap) + + :param xop: libxo handle pointer + :type xop: xo_handle_t * + :param fmt: Format string + :type fmt: const char * + :param vap: variadic arguments + :type xop: va_list + :returns: void + +.. c:function:: void xo_errorn (const char *fmt, ...) + + :param fmt: Format string + :type fmt: const char * + :returns: void + +.. c:function:: void xo_errorn_h (xo_handle_t *xop, const char *fmt, ...) + + :param xop: libxo handle pointer + :type xop: xo_handle_t * + :param fmt: Format string + :type fmt: const char * + :returns: void + +.. c:function:: void xo_errorn_hv (xo_handle_t *xop, int need_newline, const char *fmt, va_list vap) + + :param xop: libxo handle pointer + :type xop: xo_handle_t * + :param need_newline: boolean indicating need for trailing newline + :type need_newline: int + :param fmt: Format string + :type fmt: const char * + :param vap: variadic arguments + :type xop: va_list + :returns: void + + The `xo_error` function can be used for generic errors that should + be reported over the handle, rather than to stderr. The `xo_error` + function behaves like `xo_err` for TEXT and HTML output styles, but + puts the error into XML or JSON elements:: + + EXAMPLE:: + xo_error("Does not %s", "compute"); + XML:: + Does not compute + JSON:: + "error": { "message": "Does not compute" } + + The `xo_error_h` and `xo_error_hv` add a handle object and a + variadic-ized parameter to the signature, respectively. + + The `xo_errorn` function supplies a newline at the end the error + message if the format string does not include one. The + `xo_errorn_h` and `xo_errorn_hv` functions add a handle object and + a variadic-ized parameter to the signature, respectively. The + `xo_errorn_hv` function also adds a boolean to indicate the need for + a trailing newline. + +.. index:: xo_no_setlocale +.. index:: Locale + +xo_no_setlocale +~~~~~~~~~~~~~~~ + +.. c:function:: void xo_no_setlocale (void) + + libxo automatically initializes the locale based on setting of the + environment variables LC_CTYPE, LANG, and LC_ALL. The first of this + list of variables is used and if none of the variables, the locale + defaults to "UTF-8". The caller may wish to avoid this behavior, + and can do so by calling the `xo_no_setlocale` function. + +Emitting syslog Messages +------------------------ + +syslog is the system logging facility used throughout the unix world. +Messages are sent from commands, applications, and daemons to a +hierarchy of servers, where they are filtered, saved, and forwarded +based on configuration behaviors. + +syslog is an older protocol, originally documented only in source +code. By the time :RFC:`3164` published, variation and mutation left the +leading "" string as only common content. :RFC:`5424` defines a new +version (version 1) of syslog and introduces structured data into the +messages. Structured data is a set of name/value pairs transmitted +distinctly alongside the traditional text message, allowing filtering +on precise values instead of regular expressions. + +These name/value pairs are scoped by a two-part identifier; an +enterprise identifier names the party responsible for the message +catalog and a name identifying that message. `Enterprise IDs`_ are +defined by IANA, the Internet Assigned Numbers Authority. + +.. _Enterprise IDs: + https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers + +Use the `xo_set_syslog_enterprise_id` function to set the Enterprise +ID, as needed. + +The message name should follow the conventions in +:ref:`good-field-names`\ , as should the fields within the message:: + + /* Both of these calls are optional */ + xo_set_syslog_enterprise_id(32473); + xo_open_log("my-program", 0, LOG_DAEMON); + + /* Generate a syslog message */ + xo_syslog(LOG_ERR, "upload-failed", + "error <%d> uploading file '{:filename}' " + "as '{:target/%s:%s}'", + code, filename, protocol, remote); + + xo_syslog(LOG_INFO, "poofd-invalid-state", + "state {:current/%u} is invalid {:connection/%u}", + state, conn); + +The developer should be aware that the message name may be used in the +future to allow access to further information, including +documentation. Care should be taken to choose quality, descriptive +names. + +.. _syslog-details: + +Priority, Facility, and Flags +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The `xo_syslog`, `xo_vsyslog`, and `xo_open_log` functions +accept a set of flags which provide the priority of the message, the +source facility, and some additional features. These values are OR'd +together to create a single integer argument:: + + xo_syslog(LOG_ERR | LOG_AUTH, "login-failed", + "Login failed; user '{:user}' from host '{:address}'", + user, addr); + +These values are defined in . + +The priority value indicates the importance and potential impact of +each message: + + ============= ======================================================= + Priority Description + ============= ======================================================= + LOG_EMERG A panic condition, normally broadcast to all users + LOG_ALERT A condition that should be corrected immediately + LOG_CRIT Critical conditions + LOG_ERR Generic errors + LOG_WARNING Warning messages + LOG_NOTICE Non-error conditions that might need special handling + LOG_INFO Informational messages + LOG_DEBUG Developer-oriented messages + ============= ======================================================= + +The facility value indicates the source of message, in fairly generic +terms: + + =============== ======================================================= + Facility Description + =============== ======================================================= + LOG_AUTH The authorization system (e.g. :manpage:`login(1)`) + LOG_AUTHPRIV As LOG_AUTH, but logged to a privileged file + LOG_CRON The cron daemon: :manpage:`cron(8)` + LOG_DAEMON System daemons, not otherwise explicitly listed + LOG_FTP The file transfer protocol daemons + LOG_KERN Messages generated by the kernel + LOG_LPR The line printer spooling system + LOG_MAIL The mail system + LOG_NEWS The network news system + LOG_SECURITY Security subsystems, such as :manpage:`ipfw(4)` + LOG_SYSLOG Messages generated internally by :manpage:`syslogd(8)` + LOG_USER Messages generated by user processes (default) + LOG_UUCP The uucp system + LOG_LOCAL0..7 Reserved for local use + =============== ======================================================= + +In addition to the values listed above, xo_open_log accepts a set of +addition flags requesting specific logging behaviors: + + ============ ==================================================== + Flag Description + ============ ==================================================== + LOG_CONS If syslogd fails, attempt to write to /dev/console + LOG_NDELAY Open the connection to :manpage:`syslogd(8)` immediately + LOG_PERROR Write the message also to standard error output + LOG_PID Log the process id with each message + ============ ==================================================== + +.. index:: xo_syslog + +xo_syslog +~~~~~~~~~ + +.. c:function:: void xo_syslog (int pri, const char *name, const char *fmt, ...) + + :param int pri: syslog priority + :param name: Name of the syslog event + :type name: const char * + :param fmt: Format string, followed by arguments + :type fmt: const char * + :returns: void + + Use the `xo_syslog` function to generate syslog messages by calling + it with a log priority and facility, a message name, a format + string, and a set of arguments. The priority/facility argument are + discussed above, as is the message name. + + The format string follows the same conventions as `xo_emit`'s format + string, with each field being rendered as an SD-PARAM pair:: + + xo_syslog(LOG_ERR, "poofd-missing-file", + "'{:filename}' not found: {:error/%m}", filename); + + ... [poofd-missing-file@32473 filename="/etc/poofd.conf" + error="Permission denied"] '/etc/poofd.conf' not + found: Permission denied + +Support functions +~~~~~~~~~~~~~~~~~ + +.. index:: xo_vsyslog + +xo_vsyslog +++++++++++ + +.. c:function:: void xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap) + + :param int pri: syslog priority + :param name: Name of the syslog event + :type name: const char * + :param fmt: Format string + :type fmt: const char * + :param va_list vap: Variadic argument list + :returns: void + + xo_vsyslog is identical in function to xo_syslog, but takes the set of + arguments using a va_list:: + + EXAMPLE: + void + my_log (const char *name, const char *fmt, ...) + { + va_list vap; + va_start(vap, fmt); + xo_vsyslog(LOG_ERR, name, fmt, vap); + va_end(vap); + } + +.. index:: xo_open_log + +xo_open_log ++++++++++++ + +.. c:function:: void xo_open_log (const char *ident, int logopt, int facility) + + :param indent: + :type indent: const char * + :param int logopt: Bit field containing logging options + :param int facility: + :returns: void + + xo_open_log functions similar to :manpage:`openlog(3)`, allowing + customization of the program name, the log facility number, and the + additional option flags described in :ref:`syslog-details`. + +.. index:: xo_close_log + +xo_close_log +++++++++++++ + +.. c:function:: void xo_close_log (void) + + The `xo_close_log` function is similar to :manpage:`closelog(3)`, + closing the log file and releasing any associated resources. + +.. index:: xo_set_logmask + +xo_set_logmask +++++++++++++++ + +.. c:function:: int xo_set_logmask (int maskpri) + + :param int maskpri: the log priority mask + :returns: The previous log priority mask + + The `xo_set_logmask` function is similar to :manpage:`setlogmask(3)`, + restricting the set of generated log event to those whose associated + bit is set in maskpri. Use `LOG_MASK(pri)` to find the appropriate bit, + or `LOG_UPTO(toppri)` to create a mask for all priorities up to and + including toppri:: + + EXAMPLE: + setlogmask(LOG_UPTO(LOG_WARN)); + +.. index:: xo_set_syslog_enterprise_id + +xo_set_syslog_enterprise_id ++++++++++++++++++++++++++++ + +.. c:function:: void xo_set_syslog_enterprise_id (unsigned short eid) + + Use the `xo_set_syslog_enterprise_id` to supply a platform- or + application-specific enterprise id. This value is used in any future + syslog messages. + + Ideally, the operating system should supply a default value via the + "kern.syslog.enterprise_id" sysctl value. Lacking that, the + application should provide a suitable value. + +Enterprise IDs are administered by IANA, the Internet Assigned Number +Authority. The complete list is EIDs on their web site:: + + https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers + +New EIDs can be requested from IANA using the following page:: + + http://pen.iana.org/pen/PenApplication.page + +Each software development organization that defines a set of syslog +messages should register their own EID and use that value in their +software to ensure that messages can be uniquely identified by the +combination of EID + message name. + +Creating Custom Encoders +------------------------ + +The number of encoding schemes in current use is staggering, with new +and distinct schemes appearing daily. While libxo provide XML, JSON, +HMTL, and text natively, there are requirements for other encodings. + +Rather than bake support for all possible encoders into libxo, the API +allows them to be defined externally. libxo can then interfaces with +these encoding modules using a simplistic API. libxo processes all +functions calls, handles state transitions, performs all formatting, +and then passes the results as operations to a customized encoding +function, which implements specific encoding logic as required. This +means your encoder doesn't need to detect errors with unbalanced +open/close operations but can rely on libxo to pass correct data. + +By making a simple API, libxo internals are not exposed, insulating the +encoder and the library from future or internal changes. + +The three elements of the API are: + +- loading +- initialization +- operations + +The following sections provide details about these topics. + +.. index:: CBOR + +libxo source contains an encoder for Concise Binary Object +Representation, aka CBOR (:RFC:`7049`), which can be used as an +example for the API for other encoders. + +Loading Encoders +~~~~~~~~~~~~~~~~ + +Encoders can be registered statically or discovered dynamically. +Applications can choose to call the `xo_encoder_register` function +to explicitly register encoders, but more typically they are built as +shared libraries, placed in the libxo/extensions directory, and loaded +based on name. libxo looks for a file with the name of the encoder +and an extension of ".enc". This can be a file or a symlink to the +shared library file that supports the encoder:: + + % ls -1 lib/libxo/extensions/*.enc + lib/libxo/extensions/cbor.enc + lib/libxo/extensions/test.enc + +Encoder Initialization +~~~~~~~~~~~~~~~~~~~~~~ + +Each encoder must export a symbol used to access the library, which +must have the following signature:: + + int xo_encoder_library_init (XO_ENCODER_INIT_ARGS); + +`XO_ENCODER_INIT_ARGS` is a macro defined in "xo_encoder.h" that defines +an argument called "arg", a pointer of the type +`xo_encoder_init_args_t`. This structure contains two fields: + +- `xei_version` is the version number of the API as implemented + within libxo. This version is currently as 1 using + `XO_ENCODER_VERSION`. This number can be checked to ensure + compatibility. The working assumption is that all versions should + be backward compatible, but each side may need to accurately know + the version supported by the other side. `xo_encoder_library_init` + can optionally check this value, and must then set it to the version + number used by the encoder, allowing libxo to detect version + differences and react accordingly. For example, if version 2 adds + new operations, then libxo will know that an encoding library that + set `xei_version` to 1 cannot be expected to handle those new + operations. + +- xei_handler must be set to a pointer to a function of type + `xo_encoder_func_t`, as defined in "xo_encoder.h". This function + takes a set of parameters: + - xop is a pointer to the opaque `xo_handle_t` structure + - op is an integer representing the current operation + - name is a string whose meaning differs by operation + - value is a string whose meaning differs by operation + - private is an opaque structure provided by the encoder + +Additional arguments may be added in the future, so handler functions +should use the `XO_ENCODER_HANDLER_ARGS` macro. An appropriate +"extern" declaration is provided to help catch errors. + +Once the encoder initialization function has completed processing, it +should return zero to indicate that no error has occurred. A non-zero +return code will cause the handle initialization to fail. + +Operations +~~~~~~~~~~ + +The encoder API defines a set of operations representing the +processing model of libxo. Content is formatted within libxo, and +callbacks are made to the encoder's handler function when data is +ready to be processed: + + ======================= ======================================= + Operation Meaning (Base function) + ======================= ======================================= + XO_OP_CREATE Called when the handle is created + XO_OP_OPEN_CONTAINER Container opened (xo_open_container) + XO_OP_CLOSE_CONTAINER Container closed (xo_close_container) + XO_OP_OPEN_LIST List opened (xo_open_list) + XO_OP_CLOSE_LIST List closed (xo_close_list) + XO_OP_OPEN_LEAF_LIST Leaf list opened (xo_open_leaf_list) + XO_OP_CLOSE_LEAF_LIST Leaf list closed (xo_close_leaf_list) + XO_OP_OPEN_INSTANCE Instance opened (xo_open_instance) + XO_OP_CLOSE_INSTANCE Instance closed (xo_close_instance) + XO_OP_STRING Field with Quoted UTF-8 string + XO_OP_CONTENT Field with content + XO_OP_FINISH Finish any pending output + XO_OP_FLUSH Flush any buffered output + XO_OP_DESTROY Clean up resources + XO_OP_ATTRIBUTE An attribute name/value pair + XO_OP_VERSION A version string + ======================= ======================================= + +For all the open and close operations, the name parameter holds the +name of the construct. For string, content, and attribute operations, +the name parameter is the name of the field and the value parameter is +the value. "string" are differentiated from "content" to allow differing +treatment of true, false, null, and numbers from real strings, though +content values are formatted as strings before the handler is called. +For version operations, the value parameter contains the version. + +All strings are encoded in UTF-8. diff --git a/tools/libxo/doc/conf.py b/tools/libxo/doc/conf.py new file mode 100644 index 000000000..62935cf4e --- /dev/null +++ b/tools/libxo/doc/conf.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# JuniperStory documentation build configuration file, created by +# sphinx-quickstart on Tue Oct 10 10:18:55 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +import subprocess + +# +# Instead of hardcoding the version number here, we read it from the +# project's configure script +# +vers_cmd = "grep AC_INIT ../configure.ac | awk '{ print substr($2, 2, length($2) - 3);}'" +version = subprocess.check_output(vers_cmd, shell=True).decode("utf-8") + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'libxo' +copyright = '2017-2019, Juniper Networks Inc' +author = 'Phil Shafer' +default_role = 'code' +primary_domain = 'c' +smart_quotes = False + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +#version = 'develop' +# The full version, including alpha/beta/rc tags. +release = version + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinxdoc' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} +html_theme_options = { + "sidebarwidth": 320, +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +alabaster_html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + 'donate.html', + ] +} + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'libxo-manual' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'libxo.tex', 'libxo Documentation', + 'Phil Shafer', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'libxo', 'libxo Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'libxo', 'libxo Documentation', + author, 'libxo', 'A Library for Generating Text, XML, JSON, and HTML Output', + 'Miscellaneous'), +] + + + diff --git a/tools/libxo/doc/encoders.rst b/tools/libxo/doc/encoders.rst new file mode 100644 index 000000000..dfd0316bf --- /dev/null +++ b/tools/libxo/doc/encoders.rst @@ -0,0 +1,274 @@ +.. index:: encoder + +Encoders +======== + +This section gives an overview of encoders, details on the encoders +that ship with libxo, and documentation for developers of future +encoders. + +Overview +-------- + +The libxo library contains software to generate four "built-in" +formats: text, XML, JSON, and HTML. These formats are common and +useful, but there are other common and useful formats that users will +want, and including them all in the libxo software would be difficult +and cumbersome. + +To allow support for additional encodings, libxo includes a +"pluggable" extension mechanism for dynamically loading new encoders. +libxo-based applications can automatically use any installed encoder. + +Use the "encoder=XXX" option to access encoders. The following +example uses the "cbor" encoder, saving the output into a file:: + + df --libxo encoder=cbor > df-output.cbor + +Encoders can support specific options that can be accessed by +following the encoder name with a colon (':') or a plus sign ('+') and +one of more options, separated by the same character:: + + df --libxo encoder=csv+path=filesystem+leaf=name+no-header + df --libxo encoder=csv:path=filesystem:leaf=name:no-header + +These examples instructs libxo to load the "csv" encoder and pass the +following options:: + + path=filesystem + leaf=name + no-header + +Each of these option is interpreted by the encoder, and all such +options names and semantics are specific to the particular encoder. +Refer to the intended encoder for documentation on its options. + +The string "@" can be used in place of the string "encoder=". + + df --libxo @csv:no-header + +.. _csv_encoder: + +CSV - Comma Separated Values +---------------------------- + +libxo ships with a custom encoder for "CSV" files, a common format for +comma separated values. The output of the CSV encoder can be loaded +directly into spreadsheets or similar applications. + +A standard for CSV files is provided in :RFC:`4180`, but since the +format predates that standard by decades, there are many minor +differences in CSV file consumers and their expectations. The CSV +encoder has a number of options to tailor output to those +expectations. + +Consider the following XML:: + + % list-items --libxo xml,pretty + + + + GRO-000-415 + gum + 1412 + 54 + 10 + + + HRD-000-212 + rope + 85 + 4 + 2 + + + HRD-000-517 + ladder + 0 + 2 + 1 + + + + +This output is a list of `instances` (named "item"), each containing a +set of `leafs` ("sku", "name", etc). + +The CSV encoder will emit the leaf values in this output as `fields` +inside a CSV `record`, which is a line containing a set of +comma-separated values:: + + % list-items --libxo encoder=csv + sku,name,sold,in-stock,on-order + GRO-000-415,gum,1412,54,10 + HRD-000-212,rope,85,4,2 + HRD-000-517,ladder,0,2,1 + +Be aware that since the CSV encoder looks for data instances, when +used with :ref:`xo`, the `--instance` option will be needed:: + + % xo --libxo encoder=csv --instance foo 'The {:product} is {:status}\n' stereo "in route" + product,status + stereo,in route + +.. _csv_path: + +The `path` Option +~~~~~~~~~~~~~~~~~ + +By default, the CSV encoder will attempt to emit any list instance +generated by the application. In some cases, this may be +unacceptable, and a specific list may be desired. + +Use the "path" option to limit the processing of output to a specific +hierarchy. The path should be one or more names of containers or +lists. + +For example, if the "list-items" application generates other lists, +the user can give "path=top/data/item" as a path:: + + % list-items --libxo encoder=csv:path=top/data/item + sku,name,sold,in-stock,on-order + GRO-000-415,gum,1412,54,10 + HRD-000-212,rope,85,4,2 + HRD-000-517,ladder,0,2,1 + +Paths are "relative", meaning they need not be a complete set +of names to the list. This means that "path=item" may be sufficient +for the above example. + +.. _csv_leafs: + +The `leafs` Option +~~~~~~~~~~~~~~~~~~ + +The CSV encoding requires that all lines of output have the same +number of fields with the same order. In contrast, XML and JSON allow +any order (though libxo forces key leafs to appear before other +leafs). + +To maintain a consistent set of fields inside the CSV file, the same +set of leafs must be selected from each list item. By default, the +CSV encoder records the set of leafs that appear in the first list +instance it processes, and extract only those leafs from future +instances. If the first instance is missing a leaf that is desired by +the consumer, the "leaf" option can be used to ensure that an empty +value is recorded for instances that lack a particular leaf. + +The "leafs" option can also be used to exclude leafs, limiting the +output to only those leafs provided. + +In addition, the order of the output fields follows the order in which +the leafs are listed. "leafs=one.two" and "leafs=two.one" give +distinct output. + +So the "leafs" option can be used to expand, limit, and order the set +of leafs. + +The value of the leafs option should be one or more leaf names, +separated by a period ("."):: + + % list-items --libxo encoder=csv:leafs=sku.on-order + sku,on-order + GRO-000-415,10 + HRD-000-212,2 + HRD-000-517,1 + % list-items -libxo encoder=csv:leafs=on-order.sku + on-order,sku + 10,GRO-000-415 + 2,HRD-000-212 + 1,HRD-000-517 + +Note that since libxo uses terminology from YANG (:RFC:`7950`), the +data modeling language for NETCONF (:RFC:`6241`), which uses "leafs" +as the plural form of "leaf". libxo follows that convention. + +.. _csv_no_header: + +The `no-header` Option +~~~~~~~~~~~~~~~~~~~~~~ + +CSV files typical begin with a line that defines the fields included +in that file, in an attempt to make the contents self-defining:: + + sku,name,sold,in-stock,on-order + GRO-000-415,gum,1412,54,10 + HRD-000-212,rope,85,4,2 + HRD-000-517,ladder,0,2,1 + +There is no reliable mechanism for determining whether this header +line is included, so the consumer must make an assumption. + +The csv encoder defaults to producing the header line, but the +"no-header" option can be included to avoid the header line. + +.. _csv_no_quotes: + +The `no-quotes` Option +~~~~~~~~~~~~~~~~~~~~~~ + +:RFC:`4180` specifies that fields containing spaces should be quoted, but +many CSV consumers do not handle quotes. The "no-quotes" option +instruct the CSV encoder to avoid the use of quotes. + +.. _csv_dos: + +The `dos` Option +~~~~~~~~~~~~~~~~ + +:RFC:`4180` defines the end-of-line marker as a carriage return +followed by a newline. This `CRLF` convention dates from the distant +past, but its use was anchored in the 1980s by the `DOS` operating +system. + +The CSV encoder defaults to using the standard Unix end-of-line +marker, a simple newline. Use the "dos" option to use the `CRLF` +convention. + +The Encoder API +--------------- + +The encoder API consists of three distinct phases: + +- loading the encoder +- initializing the encoder +- feeding operations to the encoder + +To load the encoder, libxo will open a shared library named: + + ${prefix}/lib/libxo/encoder/${name}.enc + +This file is typically a symbolic link to a dynamic library, suitable +for `dlopen`(). libxo looks for a symbol called +`xo_encoder_library_init` inside that library and calls it with the +arguments defined in the header file "xo_encoder.h". This function +should look as follows:: + + int + xo_encoder_library_init (XO_ENCODER_INIT_ARGS) + { + arg->xei_version = XO_ENCODER_VERSION; + arg->xei_handler = test_handler; + + return 0; + } + +Several features here allow for future compatibility: the macro +XO_ENCODER_INIT_ARGS allows the arguments to this function change over +time, and the XO_ENCODER_VERSION allows the library to tell libxo +which version of the API it was compiled with. + +The function places in xei_handler should be have the signature:: + + static int + test_handler (XO_ENCODER_HANDLER_ARGS) + { + ... + +This function will be called with the "op" codes defined in +"xo_encoder.h". Each op code represents a distinct event in the libxo +processing model. For example OP_OPEN_CONTAINER tells the encoder +that a new container has been opened, and the encoder can behave in an +appropriate manner. + + diff --git a/tools/libxo/doc/example.rst b/tools/libxo/doc/example.rst new file mode 100644 index 000000000..2975ddeb1 --- /dev/null +++ b/tools/libxo/doc/example.rst @@ -0,0 +1,694 @@ + +Examples +======== + +Unit Test +--------- + +Here is one of the unit tests as an example:: + + int + main (int argc, char **argv) + { + static char base_grocery[] = "GRO"; + static char base_hardware[] = "HRD"; + struct item { + const char *i_title; + int i_sold; + int i_instock; + int i_onorder; + const char *i_sku_base; + int i_sku_num; + }; + struct item list[] = { + { "gum", 1412, 54, 10, base_grocery, 415 }, + { "rope", 85, 4, 2, base_hardware, 212 }, + { "ladder", 0, 2, 1, base_hardware, 517 }, + { "bolt", 4123, 144, 42, base_hardware, 632 }, + { "water", 17, 14, 2, base_grocery, 2331 }, + { NULL, 0, 0, 0, NULL, 0 } + }; + struct item list2[] = { + { "fish", 1321, 45, 1, base_grocery, 533 }, + }; + struct item *ip; + xo_info_t info[] = { + { "in-stock", "number", "Number of items in stock" }, + { "name", "string", "Name of the item" }, + { "on-order", "number", "Number of items on order" }, + { "sku", "string", "Stock Keeping Unit" }, + { "sold", "number", "Number of items sold" }, + { NULL, NULL, NULL }, + }; + int info_count = (sizeof(info) / sizeof(info[0])) - 1; + + argc = xo_parse_args(argc, argv); + if (argc < 0) + exit(EXIT_FAILURE); + + xo_set_info(NULL, info, info_count); + + xo_open_container_h(NULL, "top"); + + xo_open_container("data"); + xo_open_list("item"); + + for (ip = list; ip->i_title; ip++) { + xo_open_instance("item"); + + xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title); + xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n", + ip->i_sold, ip->i_sold ? ".0" : ""); + xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\n", + ip->i_instock); + xo_emit("{P: }{Lwc:On order}{:on-order/%u}\n", + ip->i_onorder); + xo_emit("{P: }{L:SKU}: {q:sku/%s-000-%u}\n", + ip->i_sku_base, ip->i_sku_num); + + xo_close_instance("item"); + } + + xo_close_list("item"); + xo_close_container("data"); + + xo_open_container("data"); + xo_open_list("item"); + + for (ip = list2; ip->i_title; ip++) { + xo_open_instance("item"); + + xo_emit("{L:Item} '{:name/%s}':\n", ip->i_title); + xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n", + ip->i_sold, ip->i_sold ? ".0" : ""); + xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\n", + ip->i_instock); + xo_emit("{P: }{Lwc:On order}{:on-order/%u}\n", + ip->i_onorder); + xo_emit("{P: }{L:SKU}: {q:sku/%s-000-%u}\n", + ip->i_sku_base, ip->i_sku_num); + + xo_close_instance("item"); + } + + xo_close_list("item"); + xo_close_container("data"); + + xo_close_container_h(NULL, "top"); + + return 0; + } + +Text output:: + + % ./testxo --libxo text + Item 'gum': + Total sold: 1412.0 + In stock: 54 + On order: 10 + SKU: GRO-000-415 + Item 'rope': + Total sold: 85.0 + In stock: 4 + On order: 2 + SKU: HRD-000-212 + Item 'ladder': + Total sold: 0 + In stock: 2 + On order: 1 + SKU: HRD-000-517 + Item 'bolt': + Total sold: 4123.0 + In stock: 144 + On order: 42 + SKU: HRD-000-632 + Item 'water': + Total sold: 17.0 + In stock: 14 + On order: 2 + SKU: GRO-000-2331 + Item 'fish': + Total sold: 1321.0 + In stock: 45 + On order: 1 + SKU: GRO-000-533 + +JSON output:: + + % ./testxo --libxo json,pretty + "top": { + "data": { + "item": [ + { + "name": "gum", + "sold": 1412.0, + "in-stock": 54, + "on-order": 10, + "sku": "GRO-000-415" + }, + { + "name": "rope", + "sold": 85.0, + "in-stock": 4, + "on-order": 2, + "sku": "HRD-000-212" + }, + { + "name": "ladder", + "sold": 0, + "in-stock": 2, + "on-order": 1, + "sku": "HRD-000-517" + }, + { + "name": "bolt", + "sold": 4123.0, + "in-stock": 144, + "on-order": 42, + "sku": "HRD-000-632" + }, + { + "name": "water", + "sold": 17.0, + "in-stock": 14, + "on-order": 2, + "sku": "GRO-000-2331" + } + ] + }, + "data": { + "item": [ + { + "name": "fish", + "sold": 1321.0, + "in-stock": 45, + "on-order": 1, + "sku": "GRO-000-533" + } + ] + } + } + +XML output:: + + % ./testxo --libxo pretty,xml + + + + gum + 1412.0 + 54 + 10 + GRO-000-415 + + + rope + 85.0 + 4 + 2 + HRD-000-212 + + + ladder + 0 + 2 + 1 + HRD-000-517 + + + bolt + 4123.0 + 144 + 42 + HRD-000-632 + + + water + 17.0 + 14 + 2 + GRO-000-2331 + + + + + fish + 1321.0 + 45 + 1 + GRO-000-533 + + + + +HMTL output:: + + % ./testxo --libxo pretty,html +
+
Item
+
'
+
gum
+
':
+
+
+
+
Total sold
+
:
+
1412.0
+
+
+
+
In stock
+
:
+
+
54
+
+
+
+
On order
+
:
+
+
10
+
+
+
+
SKU
+
:
+
GRO-000-415
+
+
+
Item
+
'
+
rope
+
':
+
+
+
+
Total sold
+
:
+
85.0
+
+
+
+
In stock
+
:
+
+
4
+
+
+
+
On order
+
:
+
+
2
+
+
+
+
SKU
+
:
+
HRD-000-212
+
+
+
Item
+
'
+
ladder
+
':
+
+
+
+
Total sold
+
:
+
0
+
+
+
+
In stock
+
:
+
+
2
+
+
+
+
On order
+
:
+
+
1
+
+
+
+
SKU
+
:
+
HRD-000-517
+
+
+
Item
+
'
+
bolt
+
':
+
+
+
+
Total sold
+
:
+
4123.0
+
+
+
+
In stock
+
:
+
+
144
+
+
+
+
On order
+
:
+
+
42
+
+
+
+
SKU
+
:
+
HRD-000-632
+
+
+
Item
+
'
+
water
+
':
+
+
+
+
Total sold
+
:
+
17.0
+
+
+
+
In stock
+
:
+
+
14
+
+
+
+
On order
+
:
+
+
2
+
+
+
+
SKU
+
:
+
GRO-000-2331
+
+
+
Item
+
'
+
fish
+
':
+
+
+
+
Total sold
+
:
+
1321.0
+
+
+
+
In stock
+
:
+
+
45
+
+
+
+
On order
+
:
+
+
1
+
+
+
+
SKU
+
:
+
GRO-000-533
+
+ +HTML output with xpath and info flags:: + + % ./testxo --libxo pretty,html,xpath,info +
+
Item
+
'
+
gum
+
':
+
+
+
+
Total sold
+
:
+
1412.0
+
+
+
+
In stock
+
:
+
+
54
+
+
+
+
On order
+
:
+
+
10
+
+
+
+
SKU
+
:
+
GRO-000-415
+
+
+
Item
+
'
+
rope
+
':
+
+
+
+
Total sold
+
:
+
85.0
+
+
+
+
In stock
+
:
+
+
4
+
+
+
+
On order
+
:
+
+
2
+
+
+
+
SKU
+
:
+
HRD-000-212
+
+
+
Item
+
'
+
ladder
+
':
+
+
+
+
Total sold
+
:
+
0
+
+
+
+
In stock
+
:
+
+
2
+
+
+
+
On order
+
:
+
+
1
+
+
+
+
SKU
+
:
+
HRD-000-517
+
+
+
Item
+
'
+
bolt
+
':
+
+
+
+
Total sold
+
:
+
4123.0
+
+
+
+
In stock
+
:
+
+
144
+
+
+
+
On order
+
:
+
+
42
+
+
+
+
SKU
+
:
+
HRD-000-632
+
+
+
Item
+
'
+
water
+
':
+
+
+
+
Total sold
+
:
+
17.0
+
+
+
+
In stock
+
:
+
+
14
+
+
+
+
On order
+
:
+
+
2
+
+
+
+
SKU
+
:
+
GRO-000-2331
+
+
+
Item
+
'
+
fish
+
':
+
+
+
+
Total sold
+
:
+
1321.0
+
+
+
+
In stock
+
:
+
+
45
+
+
+
+
On order
+
:
+
+
1
+
+
+
+
SKU
+
:
+
GRO-000-533
+
diff --git a/tools/libxo/doc/faq.rst b/tools/libxo/doc/faq.rst new file mode 100644 index 000000000..087ef710d --- /dev/null +++ b/tools/libxo/doc/faq.rst @@ -0,0 +1,208 @@ + +FAQs +==== + +This section contains the set of questions that users typically ask, +along with answers that might be helpful. + +General +------- + +Can you share the history of libxo? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In 2001, we added an XML API to the JUNOS operating system, which is +built on top of FreeBSD_. Eventually this API became standardized as +the NETCONF API (:RFC:`6241`). As part of this effort, we modified many +FreeBSD utilities to emit XML, typically via a "-X" switch. The +results were mixed. The cost of maintaining this code, updating it, +and carrying it were non-trivial, and contributed to our expense (and +the associated delay) with upgrading the version of FreeBSD on which +each release of JUNOS is based. + +.. _FreeBSD: https://www.freebsd.org + +A recent (2014) effort within JUNOS aims at removing our modifications +to the underlying FreeBSD code as a means of reducing the expense and +delay in tracking HEAD. JUNOS is structured to have system components +generate XML that is rendered by the CLI (think: login shell) into +human-readable text. This allows the API to use the same plumbing as +the CLI, and ensures that all components emit XML, and that it is +emitted with knowledge of the consumer of that XML, yielding an API +that have no incremental cost or feature delay. + +libxo is an effort to mix the best aspects of the JUNOS strategy into +FreeBSD in a seemless way, allowing commands to make printf-like +output calls with a single code path. + +Did the complex semantics of format strings evolve over time? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The history is both long and short: libxo's functionality is based +on what JUNOS does in a data modeling language called ODL (output +definition language). In JUNOS, all subcomponents generate XML, +which is feed to the CLI, where data from the ODL files tell is +how to render that XML into text. ODL might had a set of tags +like:: + + tag docsis-state { + help "State of the DOCSIS interface"; + type string; + } + + tag docsis-mode { + help "DOCSIS mode (2.0/3.0) of the DOCSIS interface"; + type string; + } + + tag docsis-upstream-speed { + help "Operational upstream speed of the interface"; + type string; + } + + tag downstream-scanning { + help "Result of scanning in downstream direction"; + type string; + } + + tag ranging { + help "Result of ranging action"; + type string; + } + + tag signal-to-noise-ratio { + help "Signal to noise ratio for all channels"; + type string; + } + + tag power { + help "Operational power of the signal on all channels"; + type string; + } + + format docsis-status-format { + picture " + State : @, Mode: @, Upstream speed: @ + Downstream scanning: @, Ranging: @ + Signal to noise ratio: @ + Power: @ + "; + line { + field docsis-state; + field docsis-mode; + field docsis-upstream-speed; + field downstream-scanning; + field ranging; + field signal-to-noise-ratio; + field power; + } + } + +These tag definitions are compiled into field definitions +that are triggered when matching XML elements are seen. ODL +also supports other means of defining output. + +The roles and modifiers describe these details. + +In moving these ideas to bsd, two things had to happen: the +formatting had to happen at the source since BSD won't have +a JUNOS-like CLI to do the rendering, and we can't depend on +external data models like ODL, which was seen as too hard a +sell to the BSD community. + +The results were that the xo_emit strings are used to encode the +roles, modifiers, names, and formats. They are dense and a bit +cryptic, but not so unlike printf format strings that developers will +be lost. + +libxo is a new implementation of these ideas and is distinct from +the previous implementation in JUNOS. + +.. index:: XOF_UNDERSCORES + +.. _good-field-names: + +What makes a good field name? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To make useful, consistent field names, follow these guidelines: + +Use lower case, even for TLAs + Lower case is more civilized. Even TLAs should be lower case + to avoid scenarios where the differences between "XPath" and + "Xpath" drive your users crazy. Using "xpath" is simpler and better. + +Use hyphens, not underscores + Use of hyphens is traditional in XML, and the XOF_UNDERSCORES + flag can be used to generate underscores in JSON, if desired. + But the raw field name should use hyphens. + +Use full words + Don't abbreviate especially when the abbreviation is not obvious or + not widely used. Use "data-size", not "dsz" or "dsize". Use + "interface" instead of "ifname", "if-name", "iface", "if", or "intf". + +Use - + Using the form - or -- helps in + making consistent, useful names, avoiding the situation where one app + uses "sent-packet" and another "packets-sent" and another + "packets-we-have-sent". The can be dropped when it is + obvious, as can obvious words in the classification. + Use "receive-after-window-packets" instead of + "received-packets-of-data-after-window". + +Reuse existing field names + Nothing's worse than writing expressions like:: + + if ($src1/process[pid == $pid]/name == + $src2/proc-table/proc-list + /prc-entry[prcss-id == $pid]/proc-name) { + ... + } + + Find someone else who is expressing similar data and follow their + fields and hierarchy. Remember the quote is not "Consistency is the + hobgoblin of little minds", but "A *foolish* consistency is the + hobgoblin of little minds". Consistency rocks! + +Use containment as scoping + In the previous example, all the names are prefixed with "proc-", + which is redundant given that they are nested under the process table. + +Think about your users + Have empathy for your users, choosing clear and useful fields that + contain clear and useful data. You may need to augment the display + content with xo_attr() calls (:ref:`xo_attr`) or "{e:}" + fields (:ref:`encoding-modifier`) to make the data useful. + +Don't use an arbitrary number postfix + What does "errors2" mean? No one will know. "errors-after-restart" + would be a better choice. Think of your users, and think of the + future. If you make "errors2", the next guy will happily make + "errors3" and before you know it, someone will be asking what's the + difference between errors37 and errors63. + +Be consistent, uniform, unsurprising, and predictable + Think of your field vocabulary as an API. You want it useful, + expressive, meaningful, direct, and obvious. You want the client + application's programmer to move between without the need to + understand a variety of opinions on how fields are named. They + should see the system as a single cohesive whole, not a sack of + cats. + +Field names constitute the means by which client programmers interact +with our system. By choosing wise names now, you are making their +lives better. + +After using `xolint` to find errors in your field descriptors, use +"`xolint -V`" to spell check your field names and to help you detect +different names for the same data. "dropped-short" and +"dropped-too-short" are both reasonable names, but using them both +will lead users to ask the difference between the two fields. If +there is no difference, use only one of the field names. If there is +a difference, change the names to make that difference more obvious. + +What does this message mean? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. include:: xolint.rst diff --git a/tools/libxo/doc/field-formatting.rst b/tools/libxo/doc/field-formatting.rst new file mode 100644 index 000000000..b182fcee9 --- /dev/null +++ b/tools/libxo/doc/field-formatting.rst @@ -0,0 +1,370 @@ + +.. index:: Field Formatting + +Field Formatting +---------------- + +The field format is similar to the format string for printf(3). Its +use varies based on the role of the field, but generally is used to +format the field's contents. + +If the format string is not provided for a value field, it defaults to +"%s". + +Note a field definition can contain zero or more printf-style +'directives', which are sequences that start with a '%' and end with +one of following characters: "diouxXDOUeEfFgGaAcCsSp". Each directive +is matched by one of more arguments to the xo_emit function. + +The format string has the form:: + + '%' format-modifier * format-character + +The format-modifier can be: + +- a '#' character, indicating the output value should be prefixed + with '0x', typically to indicate a base 16 (hex) value. +- a minus sign ('-'), indicating the output value should be padded on + the right instead of the left. +- a leading zero ('0') indicating the output value should be padded on the + left with zeroes instead of spaces (' '). +- one or more digits ('0' - '9') indicating the minimum width of the + argument. If the width in columns of the output value is less than + the minimum width, the value will be padded to reach the minimum. +- a period followed by one or more digits indicating the maximum + number of bytes which will be examined for a string argument, or the maximum + width for a non-string argument. When handling ASCII strings this + functions as the field width but for multi-byte characters, a single + character may be composed of multiple bytes. + xo_emit will never dereference memory beyond the given number of bytes. +- a second period followed by one or more digits indicating the maximum + width for a string argument. This modifier cannot be given for non-string + arguments. +- one or more 'h' characters, indicating shorter input data. +- one or more 'l' characters, indicating longer input data. +- a 'z' character, indicating a 'size_t' argument. +- a 't' character, indicating a 'ptrdiff_t' argument. +- a ' ' character, indicating a space should be emitted before + positive numbers. +- a '+' character, indicating sign should emitted before any number. + +Note that 'q', 'D', 'O', and 'U' are considered deprecated and will be +removed eventually. + +The format character is described in the following table: + + ===== ================= ====================== + Ltr Argument Type Format + ===== ================= ====================== + d int base 10 (decimal) + i int base 10 (decimal) + o int base 8 (octal) + u unsigned base 10 (decimal) + x unsigned base 16 (hex) + X unsigned long base 16 (hex) + D long base 10 (decimal) + O unsigned long base 8 (octal) + U unsigned long base 10 (decimal) + e double [-]d.ddde+-dd + E double [-]d.dddE+-dd + f double [-]ddd.ddd + F double [-]ddd.ddd + g double as 'e' or 'f' + G double as 'E' or 'F' + a double [-]0xh.hhhp[+-]d + A double [-]0Xh.hhhp[+-]d + c unsigned char a character + C wint_t a character + s char \* a UTF-8 string + S wchar_t \* a unicode/WCS string + p void \* '%#lx' + ===== ================= ====================== + +The 'h' and 'l' modifiers affect the size and treatment of the +argument: + + ===== ============= ==================== + Mod d, i o, u, x, X + ===== ============= ==================== + hh signed char unsigned char + h short unsigned short + l long unsigned long + ll long long unsigned long long + j intmax_t uintmax_t + t ptrdiff_t ptrdiff_t + z size_t size_t + q quad_t u_quad_t + ===== ============= ==================== + +.. index:: UTF-8 +.. index:: Locale + +.. _utf-8: + +UTF-8 and Locale Strings +~~~~~~~~~~~~~~~~~~~~~~~~ + +For strings, the 'h' and 'l' modifiers affect the interpretation of +the bytes pointed to argument. The default '%s' string is a 'char \*' +pointer to a string encoded as UTF-8. Since UTF-8 is compatible with +ASCII data, a normal 7-bit ASCII string can be used. '%ls' expects a +'wchar_t \*' pointer to a wide-character string, encoded as a 32-bit +Unicode values. '%hs' expects a 'char \*' pointer to a multi-byte +string encoded with the current locale, as given by the LC_CTYPE, +LANG, or LC_ALL environment varibles. The first of this list of +variables is used and if none of the variables are set, the locale +defaults to "UTF-8". + +libxo will convert these arguments as needed to either UTF-8 (for XML, +JSON, and HTML styles) or locale-based strings for display in text +style:: + + xo_emit("All strings are utf-8 content {:tag/%ls}", + L"except for wide strings"); + + ======== ================== =============================== + Format Argument Type Argument Contents + ======== ================== =============================== + %s const char \* UTF-8 string + %S const char \* UTF-8 string (alias for '%ls') + %ls const wchar_t \* Wide character UNICODE string + %hs const char * locale-based string + ======== ================== =============================== + +.. admonition:: "Long", not "locale" + + The "*l*" in "%ls" is for "*long*", following the convention of "%ld". + It is not "*locale*", a common mis-mnemonic. "%S" is equivalent to + "%ls". + +For example, the following function is passed a locale-base name, a +hat size, and a time value. The hat size is formatted in a UTF-8 +(ASCII) string, and the time value is formatted into a wchar_t +string:: + + void print_order (const char *name, int size, + struct tm *timep) { + char buf[32]; + const char *size_val = "unknown"; + + if (size > 0) + snprintf(buf, sizeof(buf), "%d", size); + size_val = buf; + } + + wchar_t when[32]; + wcsftime(when, sizeof(when), L"%d%b%y", timep); + + xo_emit("The hat for {:name/%hs} is {:size/%s}.\n", + name, size_val); + xo_emit("It was ordered on {:order-time/%ls}.\n", + when); + } + +It is important to note that xo_emit will perform the conversion +required to make appropriate output. Text style output uses the +current locale (as described above), while XML, JSON, and HTML use +UTF-8. + +UTF-8 and locale-encoded strings can use multiple bytes to encode one +column of data. The traditional "precision'" (aka "max-width") value +for "%s" printf formatting becomes overloaded since it specifies both +the number of bytes that can be safely referenced and the maximum +number of columns to emit. xo_emit uses the precision as the former, +and adds a third value for specifying the maximum number of columns. + +In this example, the name field is printed with a minimum of 3 columns +and a maximum of 6. Up to ten bytes of data at the location given by +'name' are in used in filling those columns:: + + xo_emit("{:name/%3.10.6s}", name); + +Characters Outside of Field Definitions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Characters in the format string that are not part of a field +definition are copied to the output for the TEXT style, and are +ignored for the JSON and XML styles. For HTML, these characters are +placed in a
with class "text":: + + EXAMPLE: + xo_emit("The hat is {:size/%s}.\n", size_val); + TEXT: + The hat is extra small. + XML: + extra small + JSON: + "size": "extra small" + HTML: +
The hat is
+
extra small
+
.
+ +.. index:: errno + +"%m" Is Supported +~~~~~~~~~~~~~~~~~ + +libxo supports the '%m' directive, which formats the error message +associated with the current value of "errno". It is the equivalent +of "%s" with the argument strerror(errno):: + + xo_emit("{:filename} cannot be opened: {:error/%m}", filename); + xo_emit("{:filename} cannot be opened: {:error/%s}", + filename, strerror(errno)); + +"%n" Is Not Supported +~~~~~~~~~~~~~~~~~~~~~ + +libxo does not support the '%n' directive. It's a bad idea and we +just don't do it. + +The Encoding Format (eformat) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The "eformat" string is the format string used when encoding the field +for JSON and XML. If not provided, it defaults to the primary format +with any minimum width removed. If the primary is not given, both +default to "%s". + +Content Strings +~~~~~~~~~~~~~~~ + +For padding and labels, the content string is considered the content, +unless a format is given. + +.. index:: printf-like + +Argument Validation +~~~~~~~~~~~~~~~~~~~ + +Many compilers and tool chains support validation of printf-like +arguments. When the format string fails to match the argument list, +a warning is generated. This is a valuable feature and while the +formatting strings for libxo differ considerably from printf, many of +these checks can still provide build-time protection against bugs. + +libxo provide variants of functions that provide this ability, if the +"--enable-printflike" option is passed to the "configure" script. +These functions use the "_p" suffix, like "xo_emit_p()", +xo_emit_hp()", etc. + +The following are features of libxo formatting strings that are +incompatible with printf-like testing: + +- implicit formats, where "{:tag}" has an implicit "%s"; +- the "max" parameter for strings, where "{:tag/%4.10.6s}" means up to + ten bytes of data can be inspected to fill a minimum of 4 columns and + a maximum of 6; +- percent signs in strings, where "{:filled}%" makes a single, + trailing percent sign; +- the "l" and "h" modifiers for strings, where "{:tag/%hs}" means + locale-based string and "{:tag/%ls}" means a wide character string; +- distinct encoding formats, where "{:tag/#%s/%s}" means the display + styles (text and HTML) will use "#%s" where other styles use "%s"; + +If none of these features are in use by your code, then using the "_p" +variants might be wise: + + ================== ======================== + Function printf-like Equivalent + ================== ======================== + xo_emit_hv xo_emit_hvp + xo_emit_h xo_emit_hp + xo_emit xo_emit_p + xo_emit_warn_hcv xo_emit_warn_hcvp + xo_emit_warn_hc xo_emit_warn_hcp + xo_emit_warn_c xo_emit_warn_cp + xo_emit_warn xo_emit_warn_p + xo_emit_warnx xo_emit_warnx_p + xo_emit_err xo_emit_err_p + xo_emit_errx xo_emit_errx_p + xo_emit_errc xo_emit_errc_p + ================== ======================== + +.. index:: performance +.. index:: XOEF_RETAIN + +.. _retain: + +Retaining Parsed Format Information +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +libxo can retain the parsed internal information related to the given +format string, allowing subsequent xo_emit calls, the retained +information is used, avoiding repetitive parsing of the format string:: + + SYNTAX: + int xo_emit_f(xo_emit_flags_t flags, const char fmt, ...); + EXAMPLE: + xo_emit_f(XOEF_RETAIN, "{:some/%02d}{:thing/%-6s}{:fancy}\n", + some, thing, fancy); + +To retain parsed format information, use the XOEF_RETAIN flag to the +xo_emit_f() function. A complete set of xo_emit_f functions exist to +match all the xo_emit function signatures (with handles, varadic +argument, and printf-like flags): + + ================== ======================== + Function Flags Equivalent + ================== ======================== + xo_emit_hv xo_emit_hvf + xo_emit_h xo_emit_hf + xo_emit xo_emit_f + xo_emit_hvp xo_emit_hvfp + xo_emit_hp xo_emit_hfp + xo_emit_p xo_emit_fp + ================== ======================== + +The format string must be immutable across multiple calls to xo_emit_f(), +since the library retains the string. Typically this is done by using +static constant strings, such as string literals. If the string is not +immutable, the XOEF_RETAIN flag must not be used. + +The functions xo_retain_clear() and xo_retain_clear_all() release +internal information on either a single format string or all format +strings, respectively. Neither is required, but the library will +retain this information until it is cleared or the process exits:: + + const char *fmt = "{:name} {:count/%d}\n"; + for (i = 0; i < 1000; i++) { + xo_open_instance("item"); + xo_emit_f(XOEF_RETAIN, fmt, name[i], count[i]); + } + xo_retain_clear(fmt); + +The retained information is kept as thread-specific data. + +Example +~~~~~~~ + +In this example, the value for the number of items in stock is emitted:: + + xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\n", + instock); + +This call will generate the following output:: + + TEXT: + In stock: 144 + XML: + 144 + JSON: + "in-stock": 144, + HTML: +
+
+
In stock
+
:
+
+
144
+
+ +Clearly HTML wins the verbosity award, and this output does +not include XOF_XPATH or XOF_INFO data, which would expand the +penultimate line to:: + +
144
diff --git a/tools/libxo/doc/field-modifiers.rst b/tools/libxo/doc/field-modifiers.rst new file mode 100644 index 000000000..ba2073bbd --- /dev/null +++ b/tools/libxo/doc/field-modifiers.rst @@ -0,0 +1,353 @@ + +.. index:: Field Modifiers +.. _field-modifiers: + +Field Modifiers +~~~~~~~~~~~~~~~ + +Field modifiers are flags which modify the way content emitted for +particular output styles: + + === =============== =================================================== + M Name Description + === =============== =================================================== + a argument The content appears as a 'const char \*' argument + c colon A colon (":") is appended after the label + d display Only emit field for display styles (text/HTML) + e encoding Only emit for encoding styles (XML/JSON) + g gettext Call gettext on field's render content + h humanize (hn) Format large numbers in human-readable style + \ hn-space Humanize: Place space between numeric and unit + \ hn-decimal Humanize: Add a decimal digit, if number < 10 + \ hn-1000 Humanize: Use 1000 as divisor instead of 1024 + k key Field is a key, suitable for XPath predicates + l leaf-list Field is a leaf-list + n no-quotes Do not quote the field when using JSON style + p plural Gettext: Use comma-separated plural form + q quotes Quote the field when using JSON style + t trim Trim leading and trailing whitespace + w white A blank (" ") is appended after the label + === =============== =================================================== + +Roles and modifiers can also use more verbose names, when preceded by +a comma. For example, the modifier string "Lwc" (or "L,white,colon") +means the field has a label role (text that describes the next field) +and should be followed by a colon ('c') and a space ('w'). The +modifier string "Vkq" (or ":key,quote") means the field has a value +role (the default role), that it is a key for the current instance, +and that the value should be quoted when encoded for JSON. + +.. index:: Field Modifiers; Argument +.. _argument-modifier: + +The Argument Modifier ({a:}) +++++++++++++++++++++++++++++ + +.. index:: Field Modifiers; Argument + +The argument modifier indicates that the content of the field +descriptor will be placed as a UTF-8 string (const char \*) argument +within the xo_emit parameters:: + + EXAMPLE: + xo_emit("{La:} {a:}\n", "Label text", "label", "value"); + TEXT: + Label text value + JSON: + "label": "value" + XML: + + +The argument modifier allows field names for value fields to be passed +on the stack, avoiding the need to build a field descriptor using +snprintf. For many field roles, the argument modifier is not needed, +since those roles have specific mechanisms for arguments, such as +"{C:fg-%s}". + +.. index:: Field Modifiers; Colon +.. _colon-modifier: + +The Colon Modifier ({c:}) ++++++++++++++++++++++++++ + +.. index:: Field Modifiers; Colon + +The colon modifier appends a single colon to the data value:: + + EXAMPLE: + xo_emit("{Lc:Name}{:name}\n", "phil"); + TEXT: + Name:phil + +The colon modifier is only used for the TEXT and HTML output +styles. It is commonly combined with the space modifier ('{w:}'). +It is purely a convenience feature. + +.. index:: Field Modifiers; Display +.. _display-modifier: + +The Display Modifier ({d:}) ++++++++++++++++++++++++++++ + +.. index:: Field Modifiers; Display + +The display modifier indicated the field should only be generated for +the display output styles, TEXT and HTML:: + + EXAMPLE: + xo_emit("{Lcw:Name}{d:name} {:id/%d}\n", "phil", 1); + TEXT: + Name: phil 1 + XML: + 1 + +The display modifier is the opposite of the encoding modifier, and +they are often used to give to distinct views of the underlying data. + +.. index:: Field Modifiers; Encoding +.. _encoding-modifier: + +The Encoding Modifier ({e:}) +++++++++++++++++++++++++++++ + +.. index:: Field Modifiers; Encoding + +The display modifier indicated the field should only be generated for +the display output styles, TEXT and HTML:: + + EXAMPLE: + xo_emit("{Lcw:Name}{:name} {e:id/%d}\n", "phil", 1); + TEXT: + Name: phil + XML: + phil1 + +The encoding modifier is the opposite of the display modifier, and +they are often used to give to distinct views of the underlying data. + +.. index:: Field Modifiers; Gettext +.. _gettext-modifier: + +The Gettext Modifier ({g:}) ++++++++++++++++++++++++++++ + +.. index:: Field Modifiers; Gettext +.. index:: gettext + +The gettext modifier is used to translate individual fields using the +gettext domain (typically set using the "`{G:}`" role) and current +language settings. Once libxo renders the field value, it is passed +to gettext(3), where it is used as a key to find the native language +translation. + +In the following example, the strings "State" and "full" are passed +to gettext() to find locale-based translated strings:: + + xo_emit("{Lgwc:State}{g:state}\n", "full"); + +See :ref:`gettext-role`, :ref:`plural-modifier`, and +:ref:`i18n` for additional details. + +.. index:: Field Modifiers; Humanize +.. _humanize-modifier: + +The Humanize Modifier ({h:}) +++++++++++++++++++++++++++++ + +.. index:: Field Modifiers; Humanize + +The humanize modifier is used to render large numbers as in a +human-readable format. While numbers like "44470272" are completely +readable to computers and savants, humans will generally find "44M" +more meaningful. + +"hn" can be used as an alias for "humanize". + +The humanize modifier only affects display styles (TEXT and HMTL). +The "`no-humanize`" option (See :ref:`options`) will block +the function of the humanize modifier. + +There are a number of modifiers that affect details of humanization. +These are only available in as full names, not single characters. The +"`hn-space`" modifier places a space between the number and any +multiplier symbol, such as "M" or "K" (ex: "44 K"). The +"`hn-decimal`" modifier will add a decimal point and a single tenths +digit when the number is less than 10 (ex: "4.4K"). The "`hn-1000`" +modifier will use 1000 as divisor instead of 1024, following the +JEDEC-standard instead of the more natural binary powers-of-two +tradition:: + + EXAMPLE: + xo_emit("{h:input/%u}, {h,hn-space:output/%u}, " + "{h,hn-decimal:errors/%u}, {h,hn-1000:capacity/%u}, " + "{h,hn-decimal:remaining/%u}\n", + input, output, errors, capacity, remaining); + TEXT: + 21, 57 K, 96M, 44M, 1.2G + +In the HTML style, the original numeric value is rendered in the +"data-number" attribute on the
element:: + +
96M
+ +.. index:: Field Modifiers; Key +.. _key-modifier: + +The Key Modifier ({k:}) ++++++++++++++++++++++++ + +.. index:: Field Modifiers; Key + +The key modifier is used to indicate that a particular field helps +uniquely identify an instance of list data:: + + EXAMPLE: + xo_open_list("user"); + for (i = 0; i < num_users; i++) { + xo_open_instance("user"); + xo_emit("User {k:name} has {:count} tickets\n", + user[i].u_name, user[i].u_tickets); + xo_close_instance("user"); + } + xo_close_list("user"); + +.. index:: XOF_XPATH + +Currently the key modifier is only used when generating XPath value +for the HTML output style when XOF_XPATH is set, but other uses are +likely in the near future. + +.. index:: Field Modifiers; Leaf-List +.. _leaf-list: + +The Leaf-List Modifier ({l:}) ++++++++++++++++++++++++++++++ + +.. index:: Field Modifiers; Leaf-List + +The leaf-list modifier is used to distinguish lists where each +instance consists of only a single value. In XML, these are +rendered as single elements, where JSON renders them as arrays:: + + EXAMPLE: + for (i = 0; i < num_users; i++) { + xo_emit("Member {l:user}\n", user[i].u_name); + } + XML: + phil + pallavi + JSON: + "user": [ "phil", "pallavi" ] + +The name of the field must match the name of the leaf list. + +.. index:: Field Modifiers; No-Quotes +.. _no-quotes-modifier: + +The No-Quotes Modifier ({n:}) ++++++++++++++++++++++++++++++ + +.. index:: Field Modifiers; No-Quotes + +The no-quotes modifier (and its twin, the 'quotes' modifier) affect +the quoting of values in the JSON output style. JSON uses quotes for +string value, but no quotes for numeric, boolean, and null data. +xo_emit applies a simple heuristic to determine whether quotes are +needed, but often this needs to be controlled by the caller:: + + EXAMPLE: + const char *bool = is_true ? "true" : "false"; + xo_emit("{n:fancy/%s}", bool); + JSON: + "fancy": true + +.. index:: Field Modifiers; Plural +.. _plural-modifier: + +The Plural Modifier ({p:}) +++++++++++++++++++++++++++ + +.. index:: Field Modifiers; Plural +.. index:: gettext + +The plural modifier selects the appropriate plural form of an +expression based on the most recent number emitted and the current +language settings. The contents of the field should be the singular +and plural English values, separated by a comma:: + + xo_emit("{:bytes} {Ngp:byte,bytes}\n", bytes); + +The plural modifier is meant to work with the gettext modifier ({g:}) +but can work independently. See :ref:`gettext-modifier`. + +When used without the gettext modifier or when the message does not +appear in the message catalog, the first token is chosen when the last +numeric value is equal to 1; otherwise the second value is used, +mimicking the simple pluralization rules of English. + +When used with the gettext modifier, the ngettext(3) function is +called to handle the heavy lifting, using the message catalog to +convert the singular and plural forms into the native language. + +.. index:: Field Modifiers; Quotes +.. _quotes-modifier: + +The Quotes Modifier ({q:}) +++++++++++++++++++++++++++ + +.. index:: Field Modifiers; Quotes + +The quotes modifier (and its twin, the 'no-quotes' modifier) affect +the quoting of values in the JSON output style. JSON uses quotes for +string value, but no quotes for numeric, boolean, and null data. +xo_emit applies a simple heuristic to determine whether quotes are +needed, but often this needs to be controlled by the caller:: + + EXAMPLE: + xo_emit("{q:time/%d}", 2014); + JSON: + "year": "2014" + +The heuristic is based on the format; if the format uses any of the +following conversion specifiers, then no quotes are used:: + + d i o u x X D O U e E f F g G a A c C p + +.. index:: Field Modifiers; Trim +.. _trim-modifier: + +The Trim Modifier ({t:}) +++++++++++++++++++++++++ + +.. index:: Field Modifiers; Trim + +The trim modifier removes any leading or trailing whitespace from +the value:: + + EXAMPLE: + xo_emit("{t:description}", " some input "); + JSON: + "description": "some input" + +.. index:: Field Modifiers; White Space +.. _white-space-modifier: + +The White Space Modifier ({w:}) ++++++++++++++++++++++++++++++++ + +.. index:: Field Modifiers; White Space + +The white space modifier appends a single space to the data value:: + + EXAMPLE: + xo_emit("{Lw:Name}{:name}\n", "phil"); + TEXT: + Name phil + +The white space modifier is only used for the TEXT and HTML output +styles. It is commonly combined with the colon modifier ('{c:}'). +It is purely a convenience feature. + +Note that the sense of the 'w' modifier is reversed for the units role +({Uw:}); a blank is added before the contents, rather than after it. diff --git a/tools/libxo/doc/field-roles.rst b/tools/libxo/doc/field-roles.rst new file mode 100644 index 000000000..4de810c64 --- /dev/null +++ b/tools/libxo/doc/field-roles.rst @@ -0,0 +1,312 @@ + +.. index:: Field Roles +.. _field-roles: + +Field Roles +~~~~~~~~~~~ + +Field roles are optional, and indicate the role and formatting of the +content. The roles are listed below; only one role is permitted: + + === ============== ================================================= + R Name Description + === ============== ================================================= + C color Field has color and effect controls + D decoration Field is non-text (e.g., colon, comma) + E error Field is an error message + G gettext Call gettext(3) on the format string + L label Field is text that prefixes a value + N note Field is text that follows a value + P padding Field is spaces needed for vertical alignment + T title Field is a title value for headings + U units Field is the units for the previous value field + V value Field is the name of field (the default) + W warning Field is a warning message + [ start-anchor Begin a section of anchored variable-width text + ] stop-anchor End a section of anchored variable-width text + === ============== ================================================= + +:: + + EXAMPLE: + xo_emit("{L:Free}{D::}{P: }{:free/%u} {U:Blocks}\n", + free_blocks); + +When a role is not provided, the "*value*" role is used as the default. + +Roles and modifiers can also use more verbose names, when preceded by +a comma:: + + EXAMPLE: + xo_emit("{,label:Free}{,decoration::}{,padding: }" + "{,value:free/%u} {,units:Blocks}\n", + free_blocks); + +.. index:: Field Roles; Color +.. _color-role: + +The Color Role ({C:}) ++++++++++++++++++++++ + +Colors and effects control how text values are displayed; they are +used for display styles (TEXT and HTML):: + + xo_emit("{C:bold}{:value}{C:no-bold}\n", value); + +Colors and effects remain in effect until modified by other "C"-role +fields:: + + xo_emit("{C:bold}{C:inverse}both{C:no-bold}only inverse\n"); + +If the content is empty, the "*reset*" action is performed:: + + xo_emit("{C:both,underline}{:value}{C:}\n", value); + +The content should be a comma-separated list of zero or more colors or +display effects:: + + xo_emit("{C:bold,inverse}Ugly{C:no-bold,no-inverse}\n"); + +The color content can be either static, when placed directly within +the field descriptor, or a printf-style format descriptor can be used, +if preceded by a slash ("/"): + + xo_emit("{C:/%s%s}{:value}{C:}", need_bold ? "bold" : "", + need_underline ? "underline" : "", value); + +Color names are prefixed with either "fg-" or "bg-" to change the +foreground and background colors, respectively:: + + xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n", + fg_color, bg_color, cost); + +The following table lists the supported effects: + + =============== ================================================= + Name Description + =============== ================================================= + bg-XXXXX Change background color + bold Start bold text effect + fg-XXXXX Change foreground color + inverse Start inverse (aka reverse) text effect + no-bold Stop bold text effect + no-inverse Stop inverse (aka reverse) text effect + no-underline Stop underline text effect + normal Reset effects (only) + reset Reset colors and effects (restore defaults) + underline Start underline text effect + =============== ================================================= + +The following color names are supported: + + ========= ============================================ + Name Description + ========= ============================================ + black + blue + cyan + default Default color for foreground or background + green + magenta + red + white + yellow + ========= ============================================ + +When using colors, the developer should remember that users will +change the foreground and background colors of terminal session +according to their own tastes, so assuming that "blue" looks nice is +never safe, and is a constant annoyance to your dear author. In +addition, a significant percentage of users (1 in 12) will be color +blind. Depending on color to convey critical information is not a +good idea. Color should enhance output, but should not be used as the +sole means of encoding information. + +.. index:: Field Roles; Decoration +.. _decoration-role: + +The Decoration Role ({D:}) +++++++++++++++++++++++++++ + +Decorations are typically punctuation marks such as colons, +semi-colons, and commas used to decorate the text and make it simpler +for human readers. By marking these distinctly, HTML usage scenarios +can use CSS to direct their display parameters:: + + xo_emit("{D:((}{:name}{D:))}\n", name); + +.. index:: Field Roles; Gettext +.. _gettext-role: + +The Gettext Role ({G:}) ++++++++++++++++++++++++ + +libxo supports internationalization (i18n) through its use of +gettext(3). Use the "{G:}" role to request that the remaining part of +the format string, following the "{G:}" field, be handled using +gettext(). + +Since gettext() uses the string as the key into the message catalog, +libxo uses a simplified version of the format string that removes +unimportant field formatting and modifiers, stopping minor formatting +changes from impacting the expensive translation process. A developer +change such as changing "/%06d" to "/%08d" should not force hand +inspection of all .po files. + +The simplified version can be generated for a single message using the +"`xopo -s $text`" command, or an entire .pot can be translated using +the "`xopo -f $input -o $output`" command. + + xo_emit("{G:}Invalid token\n"); + +The {G:} role allows a domain name to be set. gettext calls will +continue to use that domain name until the current format string +processing is complete, enabling a library function to emit strings +using it's own catalog. The domain name can be either static as the +content of the field, or a format can be used to get the domain name +from the arguments. + + xo_emit("{G:libc}Service unavailable in restricted mode\n"); + +See :ref:`i18n` for additional details. + +.. index:: Field Roles; Label +.. _label-role: + +The Label Role ({L:}) ++++++++++++++++++++++ + +Labels are text that appears before a value:: + + xo_emit("{Lwc:Cost}{:cost/%u}\n", cost); + +.. index:: Field Roles; Note +.. _note-role: + +The Note Role ({N:}) +++++++++++++++++++++ + +Notes are text that appears after a value:: + + xo_emit("{:cost/%u} {N:per year}\n", cost); + +.. index:: Field Roles; Padding +.. _padding-role: + +The Padding Role ({P:}) ++++++++++++++++++++++++ + +Padding represents whitespace used before and between fields. + +The padding content can be either static, when placed directly within +the field descriptor, or a printf-style format descriptor can be used, +if preceded by a slash ("/"):: + + xo_emit("{P: }{Lwc:Cost}{:cost/%u}\n", cost); + xo_emit("{P:/%30s}{Lwc:Cost}{:cost/%u}\n", "", cost); + +.. index:: Field Roles; Title +.. _title-role: + +The Title Role ({T:}) ++++++++++++++++++++++ + +Title are heading or column headers that are meant to be displayed to +the user. The title can be either static, when placed directly within +the field descriptor, or a printf-style format descriptor can be used, +if preceded by a slash ("/"):: + + xo_emit("{T:Interface Statistics}\n"); + xo_emit("{T:/%20.20s}{T:/%6.6s}\n", "Item Name", "Cost"); + +Title fields have an extra convenience feature; if both content and +format are specified, instead of looking to the argument list for a +value, the content is used, allowing a mixture of format and content +within the field descriptor:: + + xo_emit("{T:Name/%20s}{T:Count/%6s}\n"); + +Since the incoming argument is a string, the format must be "%s" or +something suitable. + +.. index:: Field Roles; Units +.. index:: XOF_UNITS +.. _units-role: + +The Units Role ({U:}) ++++++++++++++++++++++ + +Units are the dimension by which values are measured, such as degrees, +miles, bytes, and decibels. The units field carries this information +for the previous value field:: + + xo_emit("{Lwc:Distance}{:distance/%u}{Uw:miles}\n", miles); + +Note that the sense of the 'w' modifier is reversed for units; +a blank is added before the contents, rather than after it. + +When the XOF_UNITS flag is set, units are rendered in XML as the +"units" attribute:: + + 50 + +Units can also be rendered in HTML as the "data-units" attribute:: + +
50
+ +.. index:: Field Roles; Value +.. _value-role: + +The Value Role ({V:} and {:}) ++++++++++++++++++++++++++++++ + +The value role is used to represent the a data value that is +interesting for the non-display output styles (XML and JSON). Value +is the default role; if no other role designation is given, the field +is a value. The field name must appear within the field descriptor, +followed by one or two format descriptors. The first format +descriptor is used for display styles (TEXT and HTML), while the +second one is used for encoding styles (XML and JSON). If no second +format is given, the encoding format defaults to the first format, +with any minimum width removed. If no first format is given, both +format descriptors default to "%s":: + + xo_emit("{:length/%02u}x{:width/%02u}x{:height/%02u}\n", + length, width, height); + xo_emit("{:author} wrote \"{:poem}\" in {:year/%4d}\n, + author, poem, year); + +.. index:: Field Roles; Anchor +.. _anchor-role: + +The Anchor Roles ({[:} and {]:}) +++++++++++++++++++++++++++++++++ + +The anchor roles allow a set of strings by be padded as a group, +but still be visible to xo_emit as distinct fields. Either the start +or stop anchor can give a field width and it can be either directly in +the descriptor or passed as an argument. Any fields between the start +and stop anchor are padded to meet the minimum width given. + +To give a width directly, encode it as the content of the anchor tag:: + + xo_emit("({[:10}{:min/%d}/{:max/%d}{]:})\n", min, max); + +To pass a width as an argument, use "%d" as the format, which must +appear after the "/". Note that only "%d" is supported for widths. +Using any other value could ruin your day:: + + xo_emit("({[:/%d}{:min/%d}/{:max/%d}{]:})\n", width, min, max); + +If the width is negative, padding will be added on the right, suitable +for left justification. Otherwise the padding will be added to the +left of the fields between the start and stop anchors, suitable for +right justification. If the width is zero, nothing happens. If the +number of columns of output between the start and stop anchors is less +than the absolute value of the given width, nothing happens. + +.. index:: XOF_WARN + +Widths over 8k are considered probable errors and not supported. If +XOF_WARN is set, a warning will be generated. diff --git a/tools/libxo/doc/format-strings.rst b/tools/libxo/doc/format-strings.rst new file mode 100644 index 000000000..44e02abd4 --- /dev/null +++ b/tools/libxo/doc/format-strings.rst @@ -0,0 +1,47 @@ + +.. index:: Format Strings +.. _format-strings: + +Format Strings +-------------- + +libxo uses format strings to control the rendering of data into the +various output styles. Each format string contains a set of zero or +more field descriptions, which describe independent data fields. Each +field description contains a set of modifiers, a content string, and +zero, one, or two format descriptors. The modifiers tell libxo what +the field is and how to treat it, while the format descriptors are +formatting instructions using printf-style format strings, telling +libxo how to format the field. The field description is placed inside +a set of braces, with a colon (":") after the modifiers and a slash +("/") before each format descriptors. Text may be intermixed with +field descriptions within the format string. + +The field description is given as follows:: + + '{' [ role | modifier ]* [',' long-names ]* ':' [ content ] + [ '/' field-format [ '/' encoding-format ]] '}' + +The role describes the function of the field, while the modifiers +enable optional behaviors. The contents, field-format, and +encoding-format are used in varying ways, based on the role. These +are described in the following sections. + +In the following example, three field descriptors appear. The first +is a padding field containing three spaces of padding, the second is a +label ("In stock"), and the third is a value field ("in-stock"). The +in-stock field has a "%u" format that will parse the next argument +passed to the xo_emit function as an unsigned integer:: + + xo_emit("{P: }{Lwc:In stock}{:in-stock/%u}\n", 65); + +This single line of code can generate text (" In stock: 65\n"), XML +("65"), JSON ('"in-stock": 6'), or HTML (too +lengthy to be listed here). + +While roles and modifiers typically use single character for brevity, +there are alternative names for each which allow more verbose +formatting strings. These names must be preceded by a comma, and may +follow any single-character values:: + + xo_emit("{L,white,colon:In stock}{,key:in-stock/%u}\n", 65); diff --git a/tools/libxo/doc/formatting.rst b/tools/libxo/doc/formatting.rst new file mode 100644 index 000000000..dbbdd24df --- /dev/null +++ b/tools/libxo/doc/formatting.rst @@ -0,0 +1,165 @@ + +Formatting with libxo +===================== + +Most unix commands emit text output aimed at humans. It is designed +to be parsed and understood by a user. Humans are gifted at +extracting details and pattern matching in such output. Often +programmers need to extract information from this human-oriented +output. Programmers use tools like grep, awk, and regular expressions +to ferret out the pieces of information they need. Such solutions are +fragile and require maintenance when output contents change or evolve, +along with testing and validation. + +Modern tool developers favor encoding schemes like XML and JSON, +which allow trivial parsing and extraction of data. Such formats are +simple, well understood, hierarchical, easily parsed, and often +integrate easier with common tools and environments. Changes to +content can be done in ways that do not break existing users of the +data, which can reduce maintenance costs and increase feature velocity. + +In addition, modern reality means that more output ends up in web +browsers than in terminals, making HTML output valuable. + +libxo allows a single set of function calls in source code to generate +traditional text output, as well as XML and JSON formatted data. HTML +can also be generated; "
" elements surround the traditional text +output, with attributes that detail how to render the data. + +A single libxo function call in source code is all that's required:: + + xo_emit("Connecting to {:host}.{:domain}...\n", host, domain); + + TEXT: + Connecting to my-box.example.com... + XML: + my-box + example.com + JSON: + "host": "my-box", + "domain": "example.com" + HTML: +
+
Connecting to
+
my-box
+
.
+
example.com
+
...
+
+ +Encoding Styles +--------------- + +There are four encoding styles supported by libxo: + +- TEXT output can be display on a terminal session, allowing + compatibility with traditional command line usage. +- XML output is suitable for tools like XPath and protocols like + NETCONF. +- JSON output can be used for RESTful APIs and integration with + languages like Javascript and Python. +- HTML can be matched with a small CSS file to permit rendering in any + HTML5 browser. + +In general, XML and JSON are suitable for encoding data, while TEXT is +suited for terminal output and HTML is suited for display in a web +browser (see :ref:`xohtml`). + +Text Output +~~~~~~~~~~~ + +Most traditional programs generate text output on standard output, +with contents like:: + + 36 ./src + 40 ./bin + 90 . + +In this example (taken from *du* source code), the code to generate this +data might look like:: + + printf("%d\t%s\n", num_blocks, path); + +Simple, direct, obvious. But it's only making text output. Imagine +using a single code path to make TEXT, XML, JSON or HTML, deciding at +run time which to generate. + +libxo expands on the idea of printf format strings to make a single +format containing instructions for creating multiple output styles:: + + xo_emit("{:blocks/%d}\t{:path/%s}\n", num_blocks, path); + +This line will generate the same text output as the earlier printf +call, but also has enough information to generate XML, JSON, and HTML. + +The following sections introduce the other formats. + +XML Output +~~~~~~~~~~ + +XML output consists of a hierarchical set of elements, each encoded +with a start tag and an end tag. The element should be named for data +value that it is encoding:: + + + 36 + ./src + + + 40 + ./bin + + + 90 + . + + +`XML`_ is the W3C standard for encoding data. + +.. _XML: https://w3c.org/TR/xml + +JSON Output +~~~~~~~~~~~ + +JSON output consists of a hierarchical set of objects and lists, each +encoded with a quoted name, a colon, and a value. If the value is a +string, it must be quoted, but numbers are not quoted. Objects are +encoded using braces; lists are encoded using square brackets. +Data inside objects and lists is separated using commas:: + + items: [ + { "blocks": 36, "path" : "./src" }, + { "blocks": 40, "path" : "./bin" }, + { "blocks": 90, "path" : "./" } + ] + +HTML Output +~~~~~~~~~~~ + +HTML output is designed to allow the output to be rendered in a web +browser with minimal effort. Each piece of output data is rendered +inside a
element, with a class name related to the role of the +data. By using a small set of class attribute values, a CSS +stylesheet can render the HTML into rich text that mirrors the +traditional text content. + +Additional attributes can be enabled to provide more details about the +data, including data type, description, and an XPath location:: + +
+
36
+
+
./src
+
+
+
40
+
+
./bin
+
+
+
90
+
+
./
+
diff --git a/tools/libxo/doc/getting.rst b/tools/libxo/doc/getting.rst new file mode 100644 index 000000000..1511aada5 --- /dev/null +++ b/tools/libxo/doc/getting.rst @@ -0,0 +1,185 @@ + +.. index:: Getting libxo + +Getting libxo +============= + +libxo now ships as part of the FreeBSD Operating System (as of Release +11). + +libxo source code lives on github: + + https://github.com/Juniper/libxo + +The latest release of libxo is available at: + + https://github.com/Juniper/libxo/releases + +We're using `Semantic Versioning`_ to number our releases. libxo is +open source, distributed under the BSD license. We follow the +branching scheme from `A Successful Git Branching Model`_: +we do development under the "*develop*" branch, and release from +the "*master*" branch. To clone a developer tree, run the following +command:: + + git clone https://github.com/Juniper/libxo.git -b develop + +.. _Semantic Versioning: http://semver.org/spec/v2.0.0.html +.. _A Successful Git Branching Model: + http://nvie.com/posts/a-successful-git-branching-model + +Issues, problems, and bugs should be directly to the issues page on +our github site. + +Downloading libxo Source Code +----------------------------- + +You can retrieve the source for libxo in two ways: + +A. Use a "distfile" for a specific release. We use github to maintain + our releases. Visit the `release page`_ to see the list of + releases. To download the latest, look for the release witeh the + green "Latest release" button and the green "libxo-RELEASE.tar.gz" + button under that section. + +.. _release page: https://github.com/Juniper/libxo/releases + + After downloading that release's distfile, untar it as follows:: + + tar -zxf libxo-RELEASE.tar.gz + cd libxo-RELEASE + + .. admonition:: Solaris Users + + Note: for Solaris users, your "`tar`" command lacks the "-z" flag, + so you'll need to substitute "`gzip -dc $file | tar xf -`" instead + of "`tar -zxf $file`". + +B. Use the current build from github. This gives you the most recent + source code, which might be less stable than a specific release. To + build libxo from the git repo:: + + git clone https://github.com/Juniper/libxo.git + cd libxo + + .. admonition:: Be Aware + + The github repository does **not** contain the files generated by + "*autoreconf*", with the notable exception of the "*m4*" directory. + Since these files (depcomp, configure, missing, install-sh, etc) are + generated files, we keep them out of the source code repository. + + This means that if you download the a release distfile, these files + will be ready and you'll just need to run "configure", but if you + download the source code from svn, then you'll need to run + "*autoreconf*" by hand. This step is done for you by the "*setup.sh*" + script, described in the next section. + +.. _building: + +Building libxo +-------------- + +To build libxo, you'll need to set up the build, run the "*configure*" +script, run the "*make*" command, and run the regression tests. + +The following is a summary of the commands needed. These commands are +explained in detail in the rest of this section:: + + sh bin/setup.sh + cd build + ../configure + make + make test + sudo make install + +The following sections will walk through each of these steps with +additional details and options, but the above directions should be all +that's needed. + +Setting up the build +~~~~~~~~~~~~~~~~~~~~ + +.. admonition: Note + + If you downloaded a distfile, you can skip this step. + +Run the "*setup.sh*" script to set up the build. This script runs the +"*autoreconf*" command to generate the "*configure*" script and other +generated files:: + + sh bin/setup.sh + +Note: We're are currently using autoreconf version 2.69. + +Running the "configure" Script +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Configure (and autoconf in general) provides a means of building +software in diverse environments. Our configure script supports +a set of options that can be used to adjust to your operating +environment. Use "`configure --help`" to view these options. + +We use the "*build*" directory to keep object files and generated files +away from the source tree. + +To run the configure script, change into the "*build*" directory, and +run the "*configure*" script. Add any required options to the +"`../configure`" command line:: + + cd build + ../configure + +Expect to see the "*configure*" script generate the following error:: + + /usr/bin/rm: cannot remove `libtoolT': No such file or directory + +This error is harmless and can be safely ignored. + +By default, libxo installs architecture-independent files, including +extension library files, in the /usr/local directories. To specify an +installation prefix other than /usr/local for all installation files, +include the --prefix=prefix option and specify an alternate +location. To install just the extension library files in a different, +user-defined location, include the "*--with-extensions-dir=dir*" option +and specify the location where the extension libraries will live:: + + cd build + ../configure [OPTION]... [VAR=VALUE]... + +Running the "make" Command +++++++++++++++++++++++++++ + +Once the "*configure*" script is run, build the images using the +"`make`" command:: + + make + +Running the Regression Tests +++++++++++++++++++++++++++++ + +libxo includes a set of regression tests that can be run to ensure +the software is working properly. These test are optional, but will +help determine if there are any issues running libxo on your +machine. To run the regression tests:: + + make test + +Installing libxo +~~~~~~~~~~~~~~~~ + +Once the software is built, you'll need to install libxo using the +"`make install`" command. If you are the root user, or the owner of +the installation directory, simply issue the command:: + + make install + +If you are not the "*root*" user and are using the "*sudo*" package, use:: + + sudo make install + +Verify the installation by viewing the output of "`xo --version`":: + + % xo --version + libxo version 0.3.5-git-develop + xo version 0.3.5-git-develop diff --git a/tools/libxo/doc/howto.rst b/tools/libxo/doc/howto.rst new file mode 100644 index 000000000..513572355 --- /dev/null +++ b/tools/libxo/doc/howto.rst @@ -0,0 +1,394 @@ + +Howtos: Focused Directions +========================== + +This section provides task-oriented instructions for selected tasks. +If you have a task that needs instructions, please open a request as +an enhancement issue on github. + +Howto: Report bugs +------------------ + +libxo uses github to track bugs or request enhancements. Please use +the following URL: + + https://github.com/Juniper/libxo/issues + +Howto: Install libxo +-------------------- + +libxo is open source, under a new BSD license. Source code is +available on github, as are recent releases. To get the most +current release, please visit: + + https://github.com/Juniper/libxo/releases + +After downloading and untarring the source code, building involves the +following steps:: + + sh bin/setup.sh + cd build + ../configure + make + make test + sudo make install + +libxo uses a distinct "*build*" directory to keep generated files +separated from source files. + +.. index:: configure + +Use "`../configure --help`" to display available configuration +options, which include the following:: + + --enable-warnings Turn on compiler warnings + --enable-debug Turn on debugging + --enable-text-only Turn on text-only rendering + --enable-printflike Enable use of GCC __printflike attribute + --disable-libxo-options Turn off support for LIBXO_OPTIONS + --with-gettext=PFX Specify location of gettext installation + --with-libslax-prefix=PFX Specify location of libslax config + +Compiler warnings are a very good thing, but recent compiler version +have added some very pedantic checks. While every attempt is made to +keep libxo code warning-free, warnings are now optional. If you are +doing development work on libxo, it is required that you +use --enable-warnings to keep the code warning free, but most users +need not use this option. + +.. index:: --enable-text-only + +libxo provides the `--enable-text-only` option to reduce the +footprint of the library for smaller installations. XML, JSON, and +HTML rendering logic is removed. + +.. index:: --with-gettext + +The gettext library does not provide a simple means of learning its +location, but libxo will look for it in /usr and /opt/local. If +installed elsewhere, the installer will need to provide this +information using the "`--with-gettext=/dir/path`" option. + +.. index:: libslax + +libslax is not required by libxo; it contains the "oxtradoc" program +used to format documentation. + +For additional information, see :ref:`building`. + +Howto: Convert command line applications +---------------------------------------- + +Common question: How do I convert an existing command line application? + +There are four basic steps for converting command line application to +use libxo:: + +- Setting up the context +- Converting printf calls +- Creating hierarchy +- Converting error functions + +Setting up the context +~~~~~~~~~~~~~~~~~~~~~~ + +To use libxo, you'll need to include the "xo.h" header file in your +source code files:: + + #include + +In your main() function, you'll need to call xo_parse_args to handling +argument parsing (:ref:`xo_parse_args`). This function removes +libxo-specific arguments the program's argv and returns either the +number of remaining arguments or -1 to indicate an error:: + + int + main (int argc, char **argv) + { + argc = xo_parse_args(argc, argv); + if (argc < 0) + return argc; + .... + } + +.. index:: atexit +.. index:: xo_finish_atexit + +At the bottom of your main(), you'll need to call xo_finish() to +complete output processing for the default handle (:ref:`handles`). This +is required to flush internal information buffers. libxo provides the +xo_finish_atexit function that is suitable for use with the +:manpage:`atexit(3)` function:: + + atexit(xo_finish_atexit); + +Converting printf Calls +~~~~~~~~~~~~~~~~~~~~~~~ + +The second task is inspecting code for :manpage:`printf(3)` calls and +replacing them with xo_emit() calls. The format strings are similar +in task, but libxo format strings wrap output fields in braces. The +following two calls produce identical text output:: + + OLD:: + printf("There are %d %s events\n", count, etype); + + NEW:: + xo_emit("There are {:count/%d} {:event} events\n", count, etype); + +"count" and "event" are used as names for JSON and XML output. The +"count" field uses the format "%d" and "event" uses the default "%s" +format. Both are "value" roles, which is the default role. + +Since text outside of output fields is passed verbatim, other roles +are less important, but their proper use can help make output more +useful. The "note" and "label" roles allow HTML output to recognize +the relationship between text and the associated values, allowing +appropriate "hover" and "onclick" behavior. Using the "units" role +allows the presentation layer to perform conversions when needed. The +"warning" and "error" roles allows use of color and font to draw +attention to warnings. The "padding" role makes the use of vital +whitespace more clear (:ref:`padding-role`). + +The "*title*" role indicates the headings of table and sections. This +allows HTML output to use CSS to make this relationship more obvious:: + + OLD:: + printf("Statistics:\n"); + + NEW:: + xo_emit("{T:Statistics}:\n"); + +The "*color*" roles controls foreground and background colors, as well +as effects like bold and underline (see :ref:`color-role`):: + + NEW:: + xo_emit("{C:bold}required{C:}\n"); + +Finally, the start- and stop-anchor roles allow justification and +padding over multiple fields (see :ref:`anchor-role`):: + + OLD:: + snprintf(buf, sizeof(buf), "(%u/%u/%u)", min, ave, max); + printf("%30s", buf); + + NEW:: + xo_emit("{[:30}({:minimum/%u}/{:average/%u}/{:maximum/%u}{]:}", + min, ave, max); + +Creating Hierarchy +~~~~~~~~~~~~~~~~~~ + +Text output doesn't have any sort of hierarchy, but XML and JSON +require this. Typically applications use indentation to represent +these relationship:: + + OLD:: + printf("table %d\n", tnum); + for (i = 0; i < tmax; i++) { + printf(" %s %d\n", table[i].name, table[i].size); + } + + NEW:: + xo_emit("{T:/table %d}\n", tnum); + xo_open_list("table"); + for (i = 0; i < tmax; i++) { + xo_open_instance("table"); + xo_emit("{P: }{k:name} {:size/%d}\n", + table[i].name, table[i].size); + xo_close_instance("table"); + } + xo_close_list("table"); + +The open and close list functions are used before and after the list, +and the open and close instance functions are used before and after +each instance with in the list. + +Typically these developer looks for a "for" loop as an indication of +where to put these calls. + +In addition, the open and close container functions allow for +organization levels of hierarchy:: + + OLD:: + printf("Paging information:\n"); + printf(" Free: %lu\n", free); + printf(" Active: %lu\n", active); + printf(" Inactive: %lu\n", inactive); + + NEW:: + xo_open_container("paging-information"); + xo_emit("{P: }{L:Free: }{:free/%lu}\n", free); + xo_emit("{P: }{L:Active: }{:active/%lu}\n", active); + xo_emit("{P: }{L:Inactive: }{:inactive/%lu}\n", inactive); + xo_close_container("paging-information"); + +Converting Error Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +libxo provides variants of the standard error and warning functions, +:manpage:`err(3)` and :manpage:`warn(3)`. There are two variants, one +for putting the errors on standard error, and the other writes the +errors and warnings to the handle using the appropriate encoding +style:: + + OLD:: + err(1, "cannot open output file: %s", file); + + NEW:: + xo_err(1, "cannot open output file: %s", file); + xo_emit_err(1, "cannot open output file: {:filename}", file); + +.. index:: xo_finish + +Call xo_finish +~~~~~~~~~~~~~~ + +One important item: call `xo_finish` at the end of your program so +ensure that all buffered data is written out. You can call it +explicitly call it, or use :manpage:`atexit(3)` to have +`xo_finish_atexit` called implicitly on exit:: + + OLD:: + exit(0); + + NEW:: + xo_finish(); + exit(0); + +Howto: Use "xo" in Shell Scripts +-------------------------------- + +.. admonition:: Needed + + Documentation is needed for this area. + +.. index:: Internationalization (i18n) +.. index:: gettext +.. index:: xopo + +.. _i18n: + +Howto: Internationalization (i18n) +----------------------------------------------- + + How do I use libxo to support internationalization? + +libxo allows format and field strings to be used a keys into message +catalogs to enable translation into a user's native language by +invoking the standard :manpage:`gettext(3)` functions. + +gettext setup is a bit complicated: text strings are extracted from +source files into "*portable object template*" (.pot) files using the +`xgettext` command. For each language, this template file is used as +the source for a message catalog in the "*portable object*" (.po) +format, which are translated by hand and compiled into "*machine +object*" (.mo) files using the `msgfmt` command. The .mo files are +then typically installed in the /usr/share/locale or +/opt/local/share/locale directories. At run time, the user's language +settings are used to select a .mo file which is searched for matching +messages. Text strings in the source code are used as keys to look up +the native language strings in the .mo file. + +Since the xo_emit format string is used as the key into the message +catalog, libxo removes unimportant field formatting and modifiers from +the format string before use so that minor formatting changes will not +impact the expensive translation process. We don't want a developer +change such as changing "/%06d" to "/%08d" to force hand inspection of +all .po files. The simplified version can be generated for a single +message using the `xopo -s $text` command, or an entire .pot can be +translated using the `xopo -f $input -o $output` command:: + + EXAMPLE: + % xopo -s "There are {:count/%u} {:event/%.6s} events\n" + There are {:count} {:event} events\n + + Recommended workflow: + # Extract text messages + xgettext --default-domain=foo --no-wrap \ + --add-comments --keyword=xo_emit --keyword=xo_emit_h \ + --keyword=xo_emit_warn -C -E -n --foreign-user \ + -o foo.pot.raw foo.c + + # Simplify format strings for libxo + xopo -f foo.pot.raw -o foo.pot + + # For a new language, just copy the file + cp foo.pot po/LC/my_lang/foo.po + + # For an existing language: + msgmerge --no-wrap po/LC/my_lang/foo.po \ + foo.pot -o po/LC/my_lang/foo.po.new + + # Now the hard part: translate foo.po using tools + # like poedit or emacs' po-mode + + # Compile the finished file; Use of msgfmt's "-v" option is + # strongly encouraged, so that "fuzzy" entries are reported. + msgfmt -v -o po/my_lang/LC_MESSAGES/foo.mo po/my_lang/foo.po + + # Install the .mo file + sudo cp po/my_lang/LC_MESSAGES/foo.mo \ + /opt/local/share/locale/my_lang/LC_MESSAGE/ + +Once these steps are complete, you can use the `gettext` command to +test the message catalog:: + + gettext -d foo -e "some text" + +i18n and xo_emit +~~~~~~~~~~~~~~~~ + +There are three features used in libxo used to support i18n: + +- The "{G:}" role looks for a translation of the format string. +- The "{g:}" modifier looks for a translation of the field. +- The "{p:}" modifier looks for a pluralized version of the field. + +Together these three flags allows a single function call to give +native language support, as well as libxo's normal XML, JSON, and HTML +support:: + + printf(gettext("Received %zu %s from {g:server} server\n"), + counter, ngettext("byte", "bytes", counter), + gettext("web")); + + xo_emit("{G:}Received {:received/%zu} {Ngp:byte,bytes} " + "from {g:server} server\n", counter, "web"); + +libxo will see the "{G:}" role and will first simplify the format +string, removing field formats and modifiers:: + + "Received {:received} {N:byte,bytes} from {:server} server\n" + +libxo calls :manpage:`gettext(3)` with that string to get a localized +version. If your language were *Pig Latin*, the result might look +like:: + + "Eceivedray {:received} {N:byte,bytes} omfray " + "{:server} erversay\n" + +Note the field names do not change and they should not be translated. +The contents of the note ("byte,bytes") should also not be translated, +since the "g" modifier will need the untranslated value as the key for +the message catalog. + +The field "{g:server}" requests the rendered value of the field be +translated using :manpage:`gettext(3)`. In this example, "web" would +be used. + +The field "{Ngp:byte,bytes}" shows an example of plural form using the +"{p:}" modifier with the "{g:}" modifier. The base singular and plural +forms appear inside the field, separated by a comma. At run time, +libxo uses the previous field's numeric value to decide which form to +use by calling :manpage:`ngettext(3)`. + +If a domain name is needed, it can be supplied as the content of the +{G:} role. Domain names remain in use throughout the format string +until cleared with another domain name:: + + printf(dgettext("dns", "Host %s not found: %d(%s)\n"), + name, errno, dgettext("strerror", strerror(errno))); + + xo_emit("{G:dns}Host {:hostname} not found: " + "%d({G:strerror}{g:%m})\n", name, errno); diff --git a/tools/libxo/doc/index.rst b/tools/libxo/doc/index.rst new file mode 100644 index 000000000..116be4053 --- /dev/null +++ b/tools/libxo/doc/index.rst @@ -0,0 +1,54 @@ +.. # + # Copyright (c) 2014, Juniper Networks, Inc. + # All rights reserved. + # This SOFTWARE is licensed under the LICENSE provided in the + # ../Copyright file. By downloading, installing, copying, or + # using the SOFTWARE, you agree to be bound by the terms of that + # LICENSE. + # Phil Shafer, July 2014 + # + +.. default-role:: code + +libxo - A Library for Generating Text, XML, JSON, and HTML Output +=================================================================== + +The libxo library allows an application to generate text, XML, JSON, +and HTML output, suitable for both command line use and for web +applications. The application decides at run time which output style +should be produced. By using libxo, a single source code path can +emit multiple styles of output using command line options to select +the style, along with optional behaviors. libxo includes support for +multiple output streams, pluralization, color, syslog, +:manpage:`humanized(3)` output, internationalization, and UTF-8. The +library aims to minimize the cost of migrating code to libxo. + +libxo ships as part of FreeBSD. + +.. toctree:: + :maxdepth: 3 + :caption: Documentation Contents: + + intro + getting + formatting + options + format-strings + field-roles + field-modifiers + field-formatting + api + encoders + xo + xolint + xohtml + xopo + faq + howto + example + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/tools/libxo/doc/intro.rst b/tools/libxo/doc/intro.rst new file mode 100644 index 000000000..40b3a4f4a --- /dev/null +++ b/tools/libxo/doc/intro.rst @@ -0,0 +1,90 @@ + +Introducing libxo +================= + +The libxo library allows an application to generate text, XML, JSON, +and HTML output using a common set of function calls. The application +decides at run time which output style should be produced. The +application calls a function "xo_emit" to product output that is +described in a format string. A "field descriptor" tells libxo what +the field is and what it means. Each field descriptor is placed in +braces with printf-like :ref:`format-strings`:: + + xo_emit(" {:lines/%7ju} {:words/%7ju} " + "{:characters/%7ju} {d:filename/%s}\n", + linect, wordct, charct, file); + +Each field can have a role, with the 'value' role being the default, +and the role tells libxo how and when to render that field (see +:ref:`field-roles` for details). Modifiers change how the field is +rendered in different output styles (see :ref:`field-modifiers` for +details. Output can then be generated in various style, using the +"--libxo" option:: + + % wc /etc/motd + 25 165 1140 /etc/motd + % wc --libxo xml,pretty,warn /etc/motd + + + 25 + 165 + 1140 + /etc/motd + + + % wc --libxo json,pretty,warn /etc/motd + { + "wc": { + "file": [ + { + "lines": 25, + "words": 165, + "characters": 1140, + "filename": "/etc/motd" + } + ] + } + } + % wc --libxo html,pretty,warn /etc/motd +
+
+
25
+
+
165
+
+
1140
+
+
/etc/motd
+
+ +Same code path, same format strings, same information, but it's +rendered in distinct styles based on run-time flags. + +.. admonition:: Tale of Two Code Paths + + You want to prepare for the future, but you need to live in the + present. You'd love a flying car, but need to get work done today. + You want to support features like XML, JSON, and HTML rendering to + allow integration with NETCONF, REST, and web browsers, but you need + to make text output for command line users. + + And you don't want multiple code paths that can't help but get out + of sync:: + + /* None of this "if (xml) {... } else {...}" logic */ + if (xml) { + /* some code to make xml */ + } else { + /* other code to make text */ + /* oops! forgot to add something on both clauses! */ + } + + /* And ifdefs are right out. */ + #ifdef MAKE_XML + /* icky */ + #else + /* pooh */ + #endif + + But you'd really, really like all the fancy features that modern + encoding formats can provide. libxo can help. diff --git a/tools/libxo/doc/options.rst b/tools/libxo/doc/options.rst new file mode 100644 index 000000000..79cd360a1 --- /dev/null +++ b/tools/libxo/doc/options.rst @@ -0,0 +1,184 @@ + +.. index:: --libxo +.. index:: Options + +.. _options: + +Command-line Arguments +====================== + +libxo uses command line options to trigger rendering behavior. There +are multiple conventions for passing options, all using the +"`--libxo`" option:: + + --libxo + --libxo= + --libxo: + +The *brief-options* is a series of single letter abbrevations, where +the *options* is a comma-separated list of words. Both provide access +to identical functionality. The following invocations are all +identical in outcome:: + + my-app --libxo warn,pretty arg1 + my-app --libxo=warn,pretty arg1 + my-app --libxo:WP arg1 + +Programs using libxo are expecting to call the xo_parse_args function +to parse these arguments. See :ref:`xo_parse_args` for details. + +Option Keywords +--------------- + +Options is a comma-separated list of tokens that correspond to output +styles, flags, or features: + + =============== ======================================================= + Token Action + =============== ======================================================= + color Enable colors/effects for display styles (TEXT, HTML) + colors=xxxx Adjust color output values + dtrt Enable "Do The Right Thing" mode + flush Flush after every libxo function call + flush-line Flush after every line (line-buffered) + html Emit HTML output + indent=xx Set the indentation level + info Add info attributes (HTML) + json Emit JSON output + keys Emit the key attribute for keys (XML) + log-gettext Log (via stderr) each gettext(3) string lookup + log-syslog Log (via stderr) each syslog message (via xo_syslog) + no-humanize Ignore the {h:} modifier (TEXT, HTML) + no-locale Do not initialize the locale setting + no-retain Prevent retaining formatting information + no-top Do not emit a top set of braces (JSON) + not-first Pretend the 1st output item was not 1st (JSON) + pretty Emit pretty-printed output + retain Force retaining formatting information + text Emit TEXT output + underscores Replace XML-friendly "-"s with JSON friendly "_"s + units Add the 'units' (XML) or 'data-units (HTML) attribute + warn Emit warnings when libxo detects bad calls + warn-xml Emit warnings in XML + xml Emit XML output + xpath Add XPath expressions (HTML) + =============== ======================================================= + +Most of these option are simple and direct, but some require +additional details: + +- "colors" is described in :ref:`color-mapping`. +- "flush-line" performs line buffering, even when the output is not + directed to a TTY device. +- "info" generates additional data for HTML, encoded in attributes + using names that state with "data-". +- "keys" adds a "key" attribute for XML output to indicate that a leaf + is an identifier for the list member. +- "no-humanize" avoids "humanizing" numeric output (see + :ref:`humanize-modifier` for details). +- "no-locale" instructs libxo to avoid translating output to the + current locale. +- "no-retain" disables the ability of libxo to internally retain + "compiled" information about formatting strings (see :ref:`retain` + for details). +- "underscores" can be used with JSON output to change XML-friendly + names with dashes into JSON-friendly name with underscores. +- "warn" allows libxo to emit warnings on stderr when application code + make incorrect calls. +- "warn-xml" causes those warnings to be placed in XML inside the + output. + +Brief Options +------------- + +The brief options are simple single-letter aliases to the normal +keywords, as detailed below: + + ======== ============================================= + Option Action + ======== ============================================= + c Enable color/effects for TEXT/HTML + F Force line-buffered flushing + H Enable HTML output (XO_STYLE_HTML) + I Enable info output (XOF_INFO) + i Indent by + J Enable JSON output (XO_STYLE_JSON) + k Add keys to XPATH expressions in HTML + n Disable humanization (TEXT, HTML) + P Enable pretty-printed output (XOF_PRETTY) + T Enable text output (XO_STYLE_TEXT) + U Add units to HTML output + u Change "-"s to "_"s in element names (JSON) + W Enable warnings (XOF_WARN) + X Enable XML output (XO_STYLE_XML) + x Enable XPath data (XOF_XPATH) + ======== ============================================= + +.. index:: Colors + +.. _color-mapping: + +Color Mapping +------------- + +The "colors" option takes a value that is a set of mappings from the +pre-defined set of colors to new foreground and background colors. +The value is a series of "fg/bg" values, separated by a "+". Each +pair of "fg/bg" values gives the colors to which a basic color is +mapped when used as a foreground or background color. The order is +the mappings is: + +- black +- red +- green +- yellow +- blue +- magenta +- cyan +- white + +Pairs may be skipped, leaving them mapped as normal, as are missing +pairs or single colors. + +For example consider the following xo_emit call:: + + xo_emit("{C:fg-red,bg-green}Merry XMas!!{C:}\n"); + +To turn all colored output to red-on-blue, use eight pairs of +"red/blue" mappings separated by plus signs ("+"):: + + --libxo colors=red/blue+red/blue+red/blue+red/blue+\ + red/blue+red/blue+red/blue+red/blue + +To turn the red-on-green text to magenta-on-cyan, give a "magenta" +foreground value for red (the second mapping) and a "cyan" background +to green (the third mapping):: + + --libxo colors=+magenta+/cyan + +Consider the common situation where blue output looks unreadable on a +terminal session with a black background. To turn both "blue" +foreground and background output to "yellow", give only the fifth +mapping, skipping the first four mappings with bare plus signs ("+"):: + + --libxo colors=++++yellow/yellow + +Encoders +-------- + +In addition to the four "built-in" formats, libxo supports an +extensible mechanism for adding encoders. These are activated +using the "encoder" keyword:: + + --libxo encoder=cbor + +The encoder can include encoder-specific options, separated by either +colons (":") or plus signs ("+"): + + --libxo encoder=csv+path=filesystem+leaf=name+no-header + --libxo encoder=csv:path=filesystem:leaf=name:no-header + +For brevity, the string "@" can be used in place of the string +"encoder=". + + df --libxo @csv:no-header diff --git a/tools/libxo/doc/top-link.html.in b/tools/libxo/doc/top-link.html.in new file mode 100644 index 000000000..17825fe4c --- /dev/null +++ b/tools/libxo/doc/top-link.html.in @@ -0,0 +1,9 @@ + + + + + + +

The current libxo version is @LIBXO_VERSION@.

+ + diff --git a/tools/libxo/doc/xo.rst b/tools/libxo/doc/xo.rst new file mode 100644 index 000000000..5a9e88191 --- /dev/null +++ b/tools/libxo/doc/xo.rst @@ -0,0 +1,234 @@ +.. index:: --libxo, xo +.. _xo: + +The "xo" Utility +================ + +The `xo` utility allows command line access to the functionality of +the libxo library. Using `xo`, shell scripts can emit XML, JSON, and +HTML using the same commands that emit text output. + +The style of output can be selected using a specific option: "-X" for +XML, "-J" for JSON, "-H" for HTML, or "-T" for TEXT, which is the +default. The "--style ardinalyayammetersgrayErmissionpay eniedday6otuslay-oyay-eltayay \ No newline at end of file diff --git a/tools/libxo/tests/gettext/saved/gt_01.XP.err b/tools/libxo/tests/gettext/saved/gt_01.XP.err new file mode 100644 index 000000000..e69de29bb diff --git a/tools/libxo/tests/gettext/saved/gt_01.XP.out b/tools/libxo/tests/gettext/saved/gt_01.XP.out new file mode 100644 index 000000000..456536db7 --- /dev/null +++ b/tools/libxo/tests/gettext/saved/gt_01.XP.out @@ -0,0 +1,49 @@ + + amingflay + ordsway + urningbay + ymay + ouchcay + amingflay + ordsway + urningbay + ymay + ouchcay + 0 + 1 + 2 + 3 + 4 + 1234 + 1234 + foop + 4321 + + 1234 + foop + 4321 + + 1234 + foop + 4321 + + 3 + 1.2.3 + Tue Jun 23 18:47:09 UTC 2015 + <__warning> + gt_01 + Nableuay otay ectulatobjay orwardfay elocipingvay + ectulatobjay + Ermissionpay eniedday + + <__warning> + gt_01 + automaticyay ynchronizationsay ofyay ardinalyay ammetersgray ailedfay + + ardinalyay + ammetersgray + Ermissionpay eniedday + + 6 + otuslay-oyay-eltayay + diff --git a/tools/libxo/tests/gettext/strerror.pot b/tools/libxo/tests/gettext/strerror.pot new file mode 100644 index 000000000..63da80d14 --- /dev/null +++ b/tools/libxo/tests/gettext/strerror.pot @@ -0,0 +1,472 @@ +# +# Copyright (c) 1982, 1985, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# List of system errors ala strerror() and sys_errlist +# Phil Shafer , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-07-01 16:15-0400\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "Received {:received} {N:byte,bytes} from {:from}#{:port} in {:time} ms\n" +msgstr "" + +# 0 - ENOERROR +msgid "No error: 0" +msgstr "" + +# 1 - EPERM +msgid "Operation not permitted" +msgstr "" + +# 2 - ENOENT +msgid "No such file or directory" +msgstr "" + +# 3 - ESRCH +msgid "No such process" +msgstr "" + +# 4 - EINTR +msgid "Interrupted system call" +msgstr "" + +# 5 - EIO +msgid "Input/output error" +msgstr "" + +# 6 - ENXIO +msgid "Device not configured" +msgstr "" + +# 7 - E2BIG +msgid "Argument list too long" +msgstr "" + +# 8 - ENOEXEC +msgid "Exec format error" +msgstr "" + +# 9 - EBADF +msgid "Bad file descriptor" +msgstr "" + +# 10 - ECHILD +msgid "No child processes" +msgstr "" + +# 11 - EDEADLK +msgid "Resource deadlock avoided" +msgstr "" + +# 12 - ENOMEM +msgid "Cannot allocate memory" +msgstr "" + +# 13 - EACCES +msgid "Permission denied" +msgstr "" + +# 14 - EFAULT +msgid "Bad address" +msgstr "" + +# 15 - ENOTBLK +msgid "Block device required" +msgstr "" + +# 16 - EBUSY +msgid "Device busy" +msgstr "" + +# 17 - EEXIST +msgid "File exists" +msgstr "" + +# 18 - EXDEV +msgid "Cross-device link" +msgstr "" + +# 19 - ENODEV +msgid "Operation not supported by device" +msgstr "" + +# 20 - ENOTDIR +msgid "Not a directory" +msgstr "" + +# 21 - EISDIR +msgid "Is a directory" +msgstr "" + +# 22 - EINVAL +msgid "Invalid argument" +msgstr "" + +# 23 - ENFILE +msgid "Too many open files in system" +msgstr "" + +# 24 - EMFILE +msgid "Too many open files" +msgstr "" + +# 25 - ENOTTY +msgid "Inappropriate ioctl for device" +msgstr "" + +# 26 - ETXTBSY +msgid "Text file busy" +msgstr "" + +# 27 - EFBIG +msgid "File too large" +msgstr "" + +# 28 - ENOSPC +msgid "No space left on device" +msgstr "" + +# 29 - ESPIPE +msgid "Illegal seek" +msgstr "" + +# 30 - EROFS +msgid "Read-only file system" +msgstr "" + +# 31 - EMLINK +msgid "Too many links" +msgstr "" + +# 32 - EPIPE +msgid "Broken pipe" +msgstr "" + +# +# math software +# + +# 33 - EDOM +msgid "Numerical argument out of domain" +msgstr "" + +# 34 - ERANGE +msgid "Result too large" +msgstr "" + +# +# non-blocking and interrupt i/o +# + +# 35 - EAGAIN +# 35 - EWOULDBLOCK +msgid "Resource temporarily unavailable" +msgstr "" + +# 36 - EINPROGRESS +msgid "Operation now in progress" +msgstr "" + +# 37 - EALREADY +msgid "Operation already in progress" +msgstr "" + + +# +# ipc/network software -- argument errors +# + +# 38 - ENOTSOCK +msgid "Socket operation on non-socket" +msgstr "" + +# 39 - EDESTADDRREQ +msgid "Destination address required" +msgstr "" + +# 40 - EMSGSIZE +msgid "Message too long" +msgstr "" + +# 41 - EPROTOTYPE +msgid "Protocol wrong type for socket" +msgstr "" + +# 42 - ENOPROTOOPT +msgid "Protocol not available" +msgstr "" + +# 43 - EPROTONOSUPPORT +msgid "Protocol not supported" +msgstr "" + +# 44 - ESOCKTNOSUPPORT +msgid "Socket type not supported" +msgstr "" + +# 45 - EOPNOTSUPP +msgid "Operation not supported" +msgstr "" + +# 46 - EPFNOSUPPORT +msgid "Protocol family not supported" +msgstr "" + +# 47 - EAFNOSUPPORT +msgid "Address family not supported by protocol family" +msgstr "" + +# 48 - EADDRINUSE +msgid "Address already in use" +msgstr "" + +# 49 - EADDRNOTAVAIL +msgid "Can't assign requested address" +msgstr "" + +# +# ipc/network software -- operational errors +# + +# 50 - ENETDOWN +msgid "Network is down" +msgstr "" + +# 51 - ENETUNREACH +msgid "Network is unreachable" +msgstr "" + +# 52 - ENETRESET +msgid "Network dropped connection on reset" +msgstr "" + +# 53 - ECONNABORTED +msgid "Software caused connection abort" +msgstr "" + +# 54 - ECONNRESET +msgid "Connection reset by peer" +msgstr "" + +# 55 - ENOBUFS +msgid "No buffer space available" +msgstr "" + +# 56 - EISCONN +msgid "Socket is already connected" +msgstr "" + +# 57 - ENOTCONN +msgid "Socket is not connected" +msgstr "" + +# 58 - ESHUTDOWN +msgid "Can't send after socket shutdown" +msgstr "" + +# 59 - ETOOMANYREFS +msgid "Too many references: can't splice" +msgstr "" + +# 60 - ETIMEDOUT +msgid "Operation timed out" +msgstr "" + +# 61 - ECONNREFUSED +msgid "Connection refused" +msgstr "" + +# 62 - ELOOP +msgid "Too many levels of symbolic links" +msgstr "" + +# 63 - ENAMETOOLONG +msgid "File name too long" +msgstr "" + +# +# should be rearranged +# + +# 64 - EHOSTDOWN +msgid "Host is down" +msgstr "" + +# 65 - EHOSTUNREACH +msgid "No route to host" +msgstr "" + +# 66 - ENOTEMPTY +msgid "Directory not empty" +msgstr "" + +# +# quotas & mush +# + +# 67 - EPROCLIM +msgid "Too many processes" +msgstr "" + +# 68 - EUSERS +msgid "Too many users" +msgstr "" + +# 69 - EDQUOT +msgid "Disc quota exceeded" +msgstr "" + +# +# Network File System +# + +# 70 - ESTALE +msgid "Stale NFS file handle" +msgstr "" + +# 71 - EREMOTE +msgid "Too many levels of remote in path" +msgstr "" + +# 72 - EBADRPC +msgid "RPC struct is bad" +msgstr "" + +# 73 - ERPCMISMATCH +msgid "RPC version wrong" +msgstr "" + +# 74 - EPROGUNAVAIL +msgid "RPC prog. not avail" +msgstr "" + +# 75 - EPROGMISMATCH +msgid "Program version wrong" +msgstr "" + +# 76 - EPROCUNAVAIL +msgid "Bad procedure for program" +msgstr "" + +# 77 - ENOLCK +msgid "No locks available" +msgstr "" + +# 78 - ENOSYS +msgid "Function not implemented" +msgstr "" + +# 79 - EFTYPE +msgid "Inappropriate file type or format" +msgstr "" + +# 80 - EAUTH +msgid "Authentication error" +msgstr "" + +# 81 - ENEEDAUTH +msgid "Need authenticator" +msgstr "" + +# 82 - EIDRM +msgid "Identifier removed" +msgstr "" + +# 83 - ENOMSG +msgid "No message of desired type" +msgstr "" + +# 84 - EOVERFLOW +msgid "Value too large to be stored in data type" +msgstr "" + +# 85 - ECANCELED +msgid "Operation canceled" +msgstr "" + +# 86 - EILSEQ +msgid "Illegal byte sequence" +msgstr "" + +# 87 - ENOATTR +msgid "Attribute not found" +msgstr "" + +# +# General +# + +# 88 - EDOOFUS +msgid "Programming error" +msgstr "" + +# 89 - EBADMSG +msgid "Bad message" +msgstr "" + +# 90 - EMULTIHOP +msgid "Multihop attempted" +msgstr "" + +# 91 - ENOLINK +msgid "Link has been severed" +msgstr "" + +# 92 - EPROTO +msgid "Protocol error" +msgstr "" + +# 93 - ENOTCAPABLE +msgid "Capabilities insufficient" +msgstr "" + +# 94 - ECAPMODE +msgid "Not permitted in capability mode" +msgstr "" + +# 95 - ENOTRECOVERABLE +msgid "State not recoverable" +msgstr "" + +# 96 - EOWNERDEAD +msgid "Previous owner died" +msgstr "" + +# 97 - EINTEGRITY +msgid "Integrity check failed" +msgstr "" diff --git a/tools/libxo/tests/xo/Makefile.am b/tools/libxo/tests/xo/Makefile.am new file mode 100644 index 000000000..1f3636d93 --- /dev/null +++ b/tools/libxo/tests/xo/Makefile.am @@ -0,0 +1,83 @@ +# +# $Id$ +# +# Copyright 2014, Juniper Networks, Inc. +# All rights reserved. +# This SOFTWARE is licensed under the LICENSE provided in the +# ../Copyright file. By downloading, installing, copying, or otherwise +# using the SOFTWARE, you agree to be bound by the terms of that +# LICENSE. + +AM_CFLAGS = -I${top_srcdir} -I${top_srcdir}/libxo + +# Ick: maintained by hand! +TEST_CASES = \ +xo_01.sh \ +xo_02.sh + +# TEST_CASES := $(shell cd ${srcdir} ; echo *.c ) + +EXTRA_DIST = \ + ${TEST_CASES} \ + ${addprefix saved/, ${TEST_CASES:.sh=.T.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.T.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.XP.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.XP.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.JP.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.JP.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.HP.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.HP.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.X.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.X.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.J.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.J.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.H.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.H.out}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.HIPx.err}} \ + ${addprefix saved/, ${TEST_CASES:.sh=.HIPx.out}} + +S2O = | ${SED} '1,/@@/d' + +all: + +#TEST_TRACE = set -x ; + +XO=../../xo/xo + +TEST_ONE = \ + ${CHECKER} sh ${srcdir}/$$base.sh "${XO} --libxo:W$$fmt" ${TEST_OPTS} \ + > out/$$base.$$fmt.out 2> out/$$base.$$fmt.err ; \ + ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.out out/$$base.$$fmt.out ${S2O} ; \ + ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.err out/$$base.$$fmt.err ${S2O} + +TEST_FORMATS = T XP JP HP X J H HIPx + +test tests: ${bin_PROGRAMS} + @${MKDIR} -p out + -@ ${TEST_TRACE} (for test in ${TEST_CASES} ; do \ + base=`${BASENAME} $$test .sh` ; \ + (for fmt in ${TEST_FORMATS}; do \ + echo "... $$test ... $$fmt ..."; \ + ${TEST_ONE}; \ + true; \ + done) \ + done) + +one: + -@(test=${TEST_CASE}; data=${TEST_DATA}; ${TEST_ONE} ; true) + +accept: + -@(for test in ${TEST_CASES} ; do \ + base=`${BASENAME} $$test .sh` ; \ + (for fmt in ${TEST_FORMATS}; do \ + echo "... $$test ... $$fmt ..."; \ + ${CP} out/$$base.$$fmt.out ${srcdir}/saved/$$base.$$fmt.out ; \ + ${CP} out/$$base.$$fmt.err ${srcdir}/saved/$$base.$$fmt.err ; \ + done) \ + done) + +CLEANFILES = +CLEANDIRS = out + +clean-local: + rm -rf ${CLEANDIRS} diff --git a/tools/libxo/tests/xo/saved/xo_01.H.err b/tools/libxo/tests/xo/saved/xo_01.H.err new file mode 100644 index 000000000..e69de29bb diff --git a/tools/libxo/tests/xo/saved/xo_01.H.out b/tools/libxo/tests/xo/saved/xo_01.H.out new file mode 100644 index 000000000..a8b0e4783 --- /dev/null +++ b/tools/libxo/tests/xo/saved/xo_01.H.out @@ -0,0 +1 @@ +
Item
one
is
number
001
,
color
:
red
Item
two
is
number
002
,
color
:
blue
Item
three
is
number
003
,
color
:
green
Item
four
is
number
004
,
color
:
yellow
0xdeadbeef
..
1
0xdeadbeef
..
1
0xdeadbeef
..
1
0xdeadbeef
..
1
partial line
-- rest of line
\ No newline at end of file diff --git a/tools/libxo/tests/xo/saved/xo_01.HIPx.err b/tools/libxo/tests/xo/saved/xo_01.HIPx.err new file mode 100644 index 000000000..e69de29bb diff --git a/tools/libxo/tests/xo/saved/xo_01.HIPx.out b/tools/libxo/tests/xo/saved/xo_01.HIPx.out new file mode 100644 index 000000000..51d57cd73 --- /dev/null +++ b/tools/libxo/tests/xo/saved/xo_01.HIPx.out @@ -0,0 +1,80 @@ +
+
Item
+
one
+
is
+
number
+
+
001
+
,
+
color
+
:
+
+
red
+
+
+
Item
+
two
+
is
+
number
+
+
002
+
,
+
color
+
:
+
+
blue
+
+
+
Item
+
three
+
is
+
number
+
+
003
+
,
+
color
+
:
+
+
green
+
+
+
Item
+
four
+
is
+
number
+
+
004
+
,
+
color
+
:
+
+
yellow
+
+
+
+
0xdeadbeef
+
..
+
1
+
+
+
+
0xdeadbeef
+
..
+
1
+
+
+
+
0xdeadbeef
+
..
+
1
+
+
+
+
0xdeadbeef
+
..
+
1
+
+
+
partial line
+
-- rest of line
+
diff --git a/tools/libxo/tests/xo/saved/xo_01.HP.err b/tools/libxo/tests/xo/saved/xo_01.HP.err new file mode 100644 index 000000000..e69de29bb diff --git a/tools/libxo/tests/xo/saved/xo_01.HP.out b/tools/libxo/tests/xo/saved/xo_01.HP.out new file mode 100644 index 000000000..1f8bce704 --- /dev/null +++ b/tools/libxo/tests/xo/saved/xo_01.HP.out @@ -0,0 +1,80 @@ +
+
Item
+
one
+
is
+
number
+
+
001
+
,
+
color
+
:
+
+
red
+
+
+
Item
+
two
+
is
+
number
+
+
002
+
,
+
color
+
:
+
+
blue
+
+
+
Item
+
three
+
is
+
number
+
+
003
+
,
+
color
+
:
+
+
green
+
+
+
Item
+
four
+
is
+
number
+
+
004
+
,
+
color
+
:
+
+
yellow
+
+
+
+
0xdeadbeef
+
..
+
1
+
+
+
+
0xdeadbeef
+
..
+
1
+
+
+
+
0xdeadbeef
+
..
+
1
+
+
+
+
0xdeadbeef
+
..
+
1
+
+
+
partial line
+
-- rest of line
+
diff --git a/tools/libxo/tests/xo/saved/xo_01.J.err b/tools/libxo/tests/xo/saved/xo_01.J.err new file mode 100644 index 000000000..e69de29bb diff --git a/tools/libxo/tests/xo/saved/xo_01.J.out b/tools/libxo/tests/xo/saved/xo_01.J.out new file mode 100644 index 000000000..a372383b2 --- /dev/null +++ b/tools/libxo/tests/xo/saved/xo_01.J.out @@ -0,0 +1 @@ +"top": {"item": {"name":"one","value":1,"color":"red"}, "item": {"name":"two","value":2,"color":"blue"}, "item": {"name":"three","value":3,"color":"green"}, "item": {"name":"four","value":4,"color":"yellow"}, "anchor": {"address":"0xdeadbeef","foo":1}, "anchor": {"address":"0xdeadbeef","foo":1}, "anchor": {"address":"0xdeadbeef","foo":1}, "anchor": {"address":"0xdeadbeef","foo":1}} \ No newline at end of file diff --git a/tools/libxo/tests/xo/saved/xo_01.JP.err b/tools/libxo/tests/xo/saved/xo_01.JP.err new file mode 100644 index 000000000..e69de29bb diff --git a/tools/libxo/tests/xo/saved/xo_01.JP.out b/tools/libxo/tests/xo/saved/xo_01.JP.out new file mode 100644 index 000000000..80c2b311b --- /dev/null +++ b/tools/libxo/tests/xo/saved/xo_01.JP.out @@ -0,0 +1,38 @@ +"top": { + "item": { + "name": "one", + "value": 1, + "color": "red" + }, + "item": { + "name": "two", + "value": 2, + "color": "blue" + }, + "item": { + "name": "three", + "value": 3, + "color": "green" + }, + "item": { + "name": "four", + "value": 4, + "color": "yellow" + }, + "anchor": { + "address": "0xdeadbeef", + "foo": 1 + }, + "anchor": { + "address": "0xdeadbeef", + "foo": 1 + }, + "anchor": { + "address": "0xdeadbeef", + "foo": 1 + }, + "anchor": { + "address": "0xdeadbeef", + "foo": 1 + } +} \ No newline at end of file diff --git a/tools/libxo/tests/xo/saved/xo_01.T.err b/tools/libxo/tests/xo/saved/xo_01.T.err new file mode 100644 index 000000000..e69de29bb diff --git a/tools/libxo/tests/xo/saved/xo_01.T.out b/tools/libxo/tests/xo/saved/xo_01.T.out new file mode 100644 index 000000000..731603a03 --- /dev/null +++ b/tools/libxo/tests/xo/saved/xo_01.T.out @@ -0,0 +1,9 @@ +Item one is number 001, color: red +Item two is number 002, color: blue +Item three is number 003, color: green +Item four is number 004, color: yellow + 0xdeadbeef..1 + 0xdeadbeef..1 + 0xdeadbeef..1 + 0xdeadbeef..1 +partial line -- rest of line diff --git a/tools/libxo/tests/xo/saved/xo_01.X.err b/tools/libxo/tests/xo/saved/xo_01.X.err new file mode 100644 index 000000000..e69de29bb diff --git a/tools/libxo/tests/xo/saved/xo_01.X.out b/tools/libxo/tests/xo/saved/xo_01.X.out new file mode 100644 index 000000000..ffe77fa3c --- /dev/null +++ b/tools/libxo/tests/xo/saved/xo_01.X.out @@ -0,0 +1 @@ +one1redtwo2bluethree3greenfour4yellow
0xdeadbeef
1
0xdeadbeef
1
0xdeadbeef
1
0xdeadbeef
1
\ No newline at end of file diff --git a/tools/libxo/tests/xo/saved/xo_01.XP.err b/tools/libxo/tests/xo/saved/xo_01.XP.err new file mode 100644 index 000000000..e69de29bb diff --git a/tools/libxo/tests/xo/saved/xo_01.XP.out b/tools/libxo/tests/xo/saved/xo_01.XP.out new file mode 100644 index 000000000..a9d3951f3 --- /dev/null +++ b/tools/libxo/tests/xo/saved/xo_01.XP.out @@ -0,0 +1,38 @@ + + + one + 1 + red + + + two + 2 + blue + + + three + 3 + green + + + four + 4 + yellow + + +
0xdeadbeef
+ 1 +
+ +
0xdeadbeef
+ 1 +
+ +
0xdeadbeef
+ 1 +
+ +
0xdeadbeef
+ 1 +
+
diff --git a/tools/libxo/tests/xo/saved/xo_02.H.err b/tools/libxo/tests/xo/saved/xo_02.H.err new file mode 100644 index 000000000..1a570eea5 --- /dev/null +++ b/tools/libxo/tests/xo/saved/xo_02.H.err @@ -0,0 +1,26 @@ +Usage: xo [options] format [fields] + --close Close tags for the given path + --close-instance Close an open instance name + --close-list Close an open list name + --continuation OR -C Output belongs on same line as previous output + --depth Set the depth for pretty printing + --help Display this help text + --html OR -H Generate HTML output + --instance OR -I Wrap in an instance of the given name + --json OR -J Generate JSON output + --leading-xpath OR -l Add a prefix to generated XPaths (HTML) + --not-first Indicate this object is not the first (JSON) + --open Open tags for the given path + --open-instance Open an instance given by name + --open-list Open a list given by name + --option -or -O Give formatting options + --pretty OR -p Make 'pretty' output (add indent, newlines) + --style