Commit Graph

7564 Commits

Author SHA1 Message Date
melifaro
4419c812fe * Add number:array algorithm lookup method.
Kernel changes:
* s/IPFW_TABLE_U32/IPFW_TABLE_NUMBER/
* Force "lookup <port|uid|gid|jid>" to be IPFW_TABLE_NUMBER
* Support "lookup" method for number tables
* Add number:array algorihm (i32 as key, auto-growing).

Userland changes:
* Support named tables in "lookup <tag> Table"
* Fix handling of "table(NAME,val)" case
* Support printing "number" table data.
2014-07-30 14:52:26 +00:00
melifaro
bf787a59a7 * Dump available table algorithms via "ipfw talist" cmd.
Kernel changes:
* Add type/refcount fields to table algo instances.
* Add IP_FW_TABLES_ALIST opcode to export available algorihms to userland.

Userland changes:
* Fix cores on empty input inside "ipfw table" handler.
* Add "ipfw talist" cmd to print availabled kernel algorithms.
* Change "table info" output to reflect long algorithm config lines.
2014-07-29 22:44:26 +00:00
melifaro
fa3f38a6a0 * Add generic ipfw interface tracking API
* Rewrite interface tables to use interface indexes

Kernel changes:
* Add generic interface tracking API:
 - ipfw_iface_ref (must call unlocked, performs lazy init if needed, allocates
  state & bumps ref)
 - ipfw_iface_add_ntfy(UH_WLOCK+WLOCK, links comsumer & runs its callback to
  update ifindex)
 - ipfw_iface_del_ntfy(UH_WLOCK+WLOCK, unlinks consumer)
 - ipfw_iface_unref(unlocked, drops reference)
Additionally, consumer callbacks are called in interface withdrawal/departure.

* Rewrite interface tables to use iface tracking API. Currently tables are
  implemented the following way:
  runtime data is stored as sorted array of {ifidx, val} for existing interfaces
  full data is stored inside namedobj instance (chained hashed table).

* Add IP_FW_XIFLIST opcode to dump status of tracked interfaces

* Pass @chain ptr to most non-locked algorithm callbacks:
  (prepare_add, prepare_del, flush_entry ..). This may be needed for better
  interaction of given algorithm an other ipfw subsystems

* Add optional "change_ti" algorithm handler to permit updating of
  cached table_info pointer (happens in case of table_max resize)

* Fix small bug in ipfw_list_tables()
* Add badd (insert into sorted array) and bdel (remove from sorted array) funcs

Userland changes:
* Add "iflist" cmd to print status of currently tracked interface
* Add stringnum_cmp for better interface/table names sorting
2014-07-28 19:01:25 +00:00
melifaro
505e5ae081 * Require explicit table creation before use on kernel side.
* Add resize callbacks for upcoming table-based algorithms.

Kernel changes:
* s/ipfw_modify_table/ipfw_manage_table_ent/
* Simplify add_table_entry(): make table creation a separate piece of code.
  Do not perform creation if not in "compat" mode.
* Add ability to perform modification of algorithm state (like table resize).
  The following callbacks were added:
 - prepare_mod (allocate new state, without locks)
 - fill_mod (UH_WLOCK, copy old state to new one)
 - modify (UH_WLOCK + WLOCK, switch state)
 - flush_mod (no locks, flushes allocated data)
 Given callbacks are called if table modification has been requested by add or
   delete callbacks. Additional u64 tc->'flags' field was added to pass these
   requests.
* Change add/del table ent format: permit adding/removing multiple entries
   at once (only 1 supported at the moment).

Userland changes:
* Auto-create tables with warning
2014-07-26 13:37:25 +00:00
melifaro
3f7d90b385 * Use different rule structures in kernel/userland.
* Switch kernel to use per-cpu counters for rules.
* Keep ABI/API.

Kernel changes:
* Each rules is now exported as TLV with optional extenable
  counter block (ip_fW_bcounter for base one) and
  ip_fw_rule for rule&cmd data.
* Counters needs to be explicitly requested by IPFW_CFG_GET_COUNTERS flag.
* Separate counters from rules in kernel and clean up ip_fw a bit.
* Pack each rule in IPFW_TLV_RULE_ENT tlv to ease parsing.
* Introduce versioning in container TLV (may be needed in future).
* Fix ipfw_cfg_lheader broken u64 alignment.

Userland changes:
* Use set_mask from cfg header when requesting config
* Fix incorrect read accouting in ipfw_show_config()
* Use IPFW_RULE_NOOPT flag instead of playing with _pad
* Fix "ipfw -d list": do not print counters for dynamic states
* Some small fixes
2014-07-08 23:11:15 +00:00
melifaro
7189aec01e * Prepare to pass other dynamic states via ipfw_dump_config()
Kernel changes:
* Change dump format for dynamic states:
  each state is now stored inside ipfw_obj_dyntlv
  last dynamic state is indicated by IPFW_DF_LAST flag
* Do not perform sooptcopyout() for !SOPT_GET requests.

Userland changes:
* Introduce foreach_state() function handler to ease work
  with different states passed by ipfw_dump_config().
2014-07-06 23:26:34 +00:00
melifaro
0eba52a18e * Add "lookup" table functionality to permit userland entry lookups.
* Bump table dump format preserving old ABI.

Kernel size:
* Add IP_FW_TABLE_XFIND to handle "lookup" request from userland.
* Add ta_find_tentry() algorithm callbacks/handlers to support lookups.
* Fully switch to ipfw_obj_tentry for various table dumps:
  algorithms are now required to support the latest (ipfw_obj_tentry) entry
    dump format, the rest is handled by generic dump code.
  IP_FW_TABLE_XLIST opcode version bumped (0 -> 1).
* Eliminate legacy ta_dump_entry algo handler:
  dump_table_entry() converts data from current to legacy format.

Userland side:
* Add "lookup" table parameter.
* Change the way table type is guessed: call table_get_info() first,
  and check value for IPv4/IPv6 type IFF table does not exist.
* Fix table_get_list(): do more tries if supplied buffer is not enough.
* Sparate table_show_entry() from table_show_list().
2014-07-06 18:16:04 +00:00
melifaro
99023231d3 Fully switch to named tables:
Kernel changes:
* Introduce ipfw_obj_tentry table entry structure to force u64 alignment.
* Support "update-on-existing-key" "add" bahavior (TEI_FLAGS_UPDATED).
* Use "subtype" field to distingush between IPv4 and IPv6 table records
  instead of previous hack.
* Add value type (vtype) field for kernel tables. Current types are
  number,ip and dscp
* Fix sets mask retrieval for old binaries
* Fix crash while using interface tables

Userland changes:
* Switch ipfw_table_handler() to use named-only tables.
* Add "table NAME create [type {cidr|iface|u32} [valtype {number|ip|dscp}] ..."
* Switch ipfw_table_handler to match_token()-based parser.
* Switch ipfw_sets_handler to use new ipfw_get_config() for mask  retrieval.
* Allow ipfw set X table ... syntax to permit using per-set table namespaces.
2014-07-03 22:25:59 +00:00
melifaro
75913dd997 * Add new IP_FW_XADD opcode which permits to
a) specify table ids as names
  b) add multiple rules at once.
Partially convert current code for atomic addition of multiple rules.
2014-06-29 22:35:47 +00:00
melifaro
145faf7cb6 Enable kernel-side rule filtering based on user request.
Make do_get3() function return real error.
2014-06-29 09:29:27 +00:00
melifaro
5d627fdb8b Suppord showing named tables in ipfw(8) rule listing.
Kernel changes:
* change base TLV header to be u64 (so size can be u32).
* Introduce ipfw_obj_ctlv generc container TLV.
* Add IP_FW_XGET opcode which is now used for atomic configuration
  retrieval. One can specify needed configuration pieces to retrieve
  via flags field. Currently supported are
  IPFW_CFG_GET_STATIC (static rules) and
  IPFW_CFG_GET_STATES (dynamic states).
  Other configuration pieces (tables, pipes, etc..) support is planned.

Userland changes:
* Switch ipfw(8) to use new IP_FW_XGET for rule listing.
* Split rule listing code get and show pieces.
* Make several steps forward towards libipfw:
  permit printing states and rules(paritally) to supplied buffer.
  do not die on malloc/kernel failure inside given printing functions.
  stop assuming cmdline_opts is global symbol.
2014-06-28 23:20:24 +00:00
melifaro
b06860b3e2 Simplify opcode handling.
* Use one u16 from op3 header to implement opcode versioning.
* IP_FW_TABLE_XLIST has now 2 handlers, for ver.0 (old) and ver.1 (current).
* Every getsockopt request is now handled in ip_fw_table.c
* Rename new opcodes:
IP_FW_OBJ_DEL -> IP_FW_TABLE_XDESTROY
IP_FW_OBJ_LISTSIZE -> IP_FW_TABLES_XGETSIZE
IP_FW_OBJ_LIST -> IP_FW_TABLES_XLIST
IP_FW_OBJ_INFO -> IP_FW_TABLE_XINFO
IP_FW_OBJ_INFO -> IP_FW_TABLE_XFLUSH

* Add some docs about using given opcodes.
* Group some legacy opcode/handlers.
2014-06-15 13:40:27 +00:00
melifaro
fe9646e6ff Move further to eliminate next pieces of number-assuming code inside tables.
Kernel changes:
* Add IP_FW_OBJ_FLUSH opcode (flush table based on its name/set)
* Add IP_FW_OBJ_DUMP opcode (dumps table data based on its names/set)
* Add IP_FW_OBJ_LISTSIZE / IP_FW_OBJ_LIST opcodes (get list of kernel tables)

Userland changes:
* move tables code to separate tables.c file
* get rid of tables_max
* switch "all"/list handling to new opcodes
2014-06-14 22:47:25 +00:00
melifaro
f9fb63fe8c Add API to ease adding new algorithms/new tabletypes to ipfw.
Kernel-side changelog:
* Split general tables code and algorithm-specific table data.
  Current algorithms (IPv4/IPv6 radix and interface tables radix) moved to
  new ip_fw_table_algo.c file.
  Tables code now supports any algorithm implementing the following callbacks:
+struct table_algo {
+       char            name[64];
+       int             idx;
+       ta_init         *init;
+       ta_destroy      *destroy;
+       table_lookup_t  *lookup;
+       ta_prepare_add  *prepare_add;
+       ta_prepare_del  *prepare_del;
+       ta_add          *add;
+       ta_del          *del;
+       ta_flush_entry  *flush_entry;
+       ta_foreach      *foreach;
+       ta_dump_entry   *dump_entry;
+       ta_dump_xentry  *dump_xentry;
+};

* Change ->state, ->xstate, ->tabletype fields of ip_fw_chain to
   ->tablestate pointer (array of 32 bytes structures necessary for
   runtime lookups (can be probably shrinked to 16 bytes later):

   +struct table_info {
   +       table_lookup_t  *lookup;        /* Lookup function */
   +       void            *state;         /* Lookup radix/other structure */
   +       void            *xstate;        /* eXtended state */
   +       u_long          data;           /* Hints for given func */
   +};

* Add count method for namedobj instance to ease size calculations
* Bump ip_fw3 buffer in ipfw_clt 128->256 bytes.
* Improve bitmask resizing on tables_max change.
* Remove table numbers checking from most places.
* Fix wrong nesting in ipfw_rewrite_table_uidx().

* Add IP_FW_OBJ_LIST opcode (list all objects of given type, currently
    implemented for IPFW_OBJTYPE_TABLE).
* Add IP_FW_OBJ_LISTSIZE (get buffer size to hold IP_FW_OBJ_LIST data,
    currenly implemented for IPFW_OBJTYPE_TABLE).
* Add IP_FW_OBJ_INFO (requests info for one object of given type).

Some name changes:
s/ipfw_xtable_tlv/ipfw_obj_tlv/ (no table specifics)
s/ipfw_xtable_ntlv/ipfw_obj_ntlv/ (no table specifics)

Userland changes:
* Add do_set3() cmd to ipfw2 to ease dealing with op3-embeded opcodes.
* Add/improve support for destroy/info cmds.
2014-06-14 10:58:39 +00:00
melifaro
01ec53e019 Make ipfw tables use names as used-level identifier internally:
* Add namedobject set-aware api capable of searching/allocation objects by their name/idx.
* Switch tables code to use string ids for configuration tasks.
* Change locking model: most configuration changes are protected with UH lock, runtime-visible are protected with both locks.
* Reduce number of arguments passed to ipfw_table_add/del by using separate structure.
* Add internal V_fw_tables_sets tunable (set to 0) to prepare for set-aware tables (requires opcodes/client support)
* Implement typed table referencing (and tables are implicitly allocated with all state like radix ptrs on reference)
* Add "destroy" ipfw(8) using new IP_FW_DELOBJ opcode

Namedobj more detailed:
* Blackbox api providing methods to add/del/search/enumerate objects
* Statically-sized hashes for names/indexes
* Per-set bitmask to indicate free indexes
* Separate methods for index alloc/delete/resize

Basically, there should not be any user-visible changes except the following:
* reducing table_max is not supported
* flush & add change table type won't work if table is referenced

Sponsored by:	Yandex LLC
2014-06-12 09:59:11 +00:00
ae
c78bc4087e Add disklabel64 support to GEOM_PART class.
This partitioning scheme is used in DragonFlyBSD. It is similar to
BSD disklabel, but has the following improvements:
* metadata has own dedicated place and isn't accessible through partitions;
* all offsets are 64-bit;
* supports 16 partitions by default (has reserved place for more);
* has reserved place for backup label (but not yet implemented);
* has UUIDs for partitions and partition types;

No objections from:	geom
MFC after:	2 weeks
Relnotes:	yes
2014-06-11 10:42:34 +00:00
bdrewery
989e2c6000 In preparation for ASLR [1] support add WITH_PIE to support building with -fPIE.
This is currently an opt-in build flag. Once ASLR support is ready and stable
it should changed to opt-out and be enabled by default along with ASLR.

Each application Makefile uses opt-out to ensure that ASLR will be enabled by
default in new directories when the system is compiled with PIE/ASLR. [2]

Mark known build failures as NO_PIE for now.

The only known runtime failure was rtld.

[1] http://www.bsdcan.org/2014/schedule/events/452.en.html
Submitted by:		Shawn Webb <lattera@gmail.com>
Discussed between:	des@ and Shawn Webb [2]
2014-06-08 17:29:31 +00:00
joel
1f9618e6f7 Minor mdoc improvements. 2014-06-06 19:00:43 +00:00
pjd
7132d23023 The 'create' subcommand doesn't have '-h' option. 2014-06-06 13:00:53 +00:00
allanjude
13ec5f36b0 Style cleanups on ifconfig.8
fix igor warnings
uppercase all instances of Ethernet
replace bad e.g.

CR:		D91
Approved by:	wblock (mentor)
2014-06-06 00:22:19 +00:00
ivoras
5fab5f26be Bulk document the kern.geom.label.*.enable sysctls and tunables. 2014-06-04 16:29:18 +00:00
ivoras
da8de155a0 Document the diskid automatic label class.
While there, also document the glabel "native" labels and explain why
there are additional nodes created for nested GEOM classes.

Reminded by:	jmg
2014-06-02 15:05:25 +00:00
hiren
cc47b6d947 ECN marking implenetation for dummynet.
Changes include both DCTCP and RFC 3168 ECN marking methodology.

DCTCP draft: http://tools.ietf.org/html/draft-bensley-tcpm-dctcp-00

Submitted by:	Midori Kato (aoimidori27@gmail.com)
Worked with:	Lars Eggert (lars@netapp.com)
Reviewed by:	luigi, hiren
2014-06-01 07:28:24 +00:00
allanjude
f7278db038 improve ifconfig(8) man page by describing special behaviour of -l ether
PR:		docs/187644
Submitted by:	Andrew Merenbach (original patch)
Approved by:	bcr (mentor)
2014-05-27 20:45:15 +00:00
trhodes
f22bac81aa If called without -T or -t, fsck attempts to detect the
file system type.  If this fails, fsck will fail with
"unknown file system type" message.

PR:		188214
2014-05-23 14:32:57 +00:00
marck
2dc0b17921 Document VMware-related filesystems additions.
Reviewed by:    jmg
MFC after:      1 week
2014-05-21 05:27:57 +00:00
bjk
e0a0a75cf1 Assorted updates to md5.1
Note that the -c argument's parameter is compared against the digest of
the file, not the file. [1]

Update the "current time" parentheticals for notes about reversing
and colliding the hash functions. [1]

Some general mdoc updates.

PR:		docs/188043 [1]
Submitted by:	Jamie Landeg-Jones [1]
Approved by:	hrs (mentor)
MFC after:	1 week
2014-05-18 21:16:59 +00:00
melifaro
f4783a05e9 Fix wrong formatting of 0.0.0.0/X table records in ipfw(8).
Add `flags` u16 field to the hole in ipfw_table_xentry structure.
Kernel has been guessing address family for supplied record based
on xent length size.
Userland, however, has been getting fixed-size ipfw_table_xentry structures
guessing address family by checking address by IN6_IS_ADDR_V4COMPAT().

Fix this behavior by providing specific IPFW_TCF_INET flag for IPv4 records.

PR:		bin/189471
Submitted by:	Dennis Yusupoff <dyr@smartspb.net>
MFC after:	2 weeks
2014-05-17 13:45:03 +00:00
thomas
681730d4b1 Add mention of metadata version 7 in FreeBSD 10.0
Reviewed by:	pjd
MFC after:	1 day
2014-05-13 15:46:52 +00:00
melifaro
4a170f05aa Fix incorrect netmasks being passed via rtsock.
Since radix has been ignoring sa_family in passed sockaddrs,
no one ever has bothered filling valid sa_family in netmasks.
Additionally, radix adjusts sa_len field in every netmask not to
compare zero bytes at all.

This leads us to rt_mask with sa_family of AF_UNSPEC (-1) and
arbitrary sa_len field (0 for default route, for example).

However, rtsock have been passing that rt_mask intact for ages,
requiring all rtsock consumers to make ther own local hacks.
We even have unfixed on in base:

do `route -n monitor` in one window and issue `route -n get addr`
for some directly-connected address. You will probably see the following:

got message of size 304 on Thu May  8 15:06:06 2014
RTM_GET: Report Metrics: len 304, pid: 30493, seq 1, errno 0, flags:<UP,DONE,PINNED>
locks:  inits:
sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA>
 10.0.0.0 link#1 (255) ffff ffff ff em0:8.0.27.c5.29.d4 10.0.0.92
_________________^^^^^^^^^^^^^^^^^^

after the change:

got message of size 312 on Thu May  8 15:44:07 2014
RTM_GET: Report Metrics: len 312, pid: 2895, seq 1, errno 0, flags:<UP,DONE,PINNED>
locks:  inits:
sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA>
 10.0.0.0 link#1 255.255.255.0 em0:8.0.27.c5.29.d4 10.0.0.92
_________________^^^^^^^^^^^^^^^^^^

Sponsored by:	Yandex LLC
MFC after:	1 month
2014-05-08 11:56:06 +00:00
marius
8d7e1b3f39 - Sprinkle const and static as appropriate.
- Fix whitespace bugs.
- Remove pointless returns in void functions.
- Nuke pointless switch cases mirroring the default.

MFC after:	3 days
Sponsored by:	Bally Wulff Games & Entertainment GmbH
2014-05-07 09:15:46 +00:00
marius
72755774fc - Allow foot shooting with the resetconfig command via the -f option.
- Fix typos preventing -f to actually work with the create command.
- Initialize flags to zero rather than using stack garbage when handling
  the grow command.

MFC after:	3 days
Sponsored by:	Bally Wulff Games & Entertainment GmbH
2014-05-06 16:29:02 +00:00
imp
2118f42afd Use src.opts.mk in preference to bsd.own.mk except where we need stuff
from the latter.
2014-05-06 04:22:01 +00:00
asomers
cef1d11432 Remove the ifconfig test added in rev 263445. After discussion with
melifaro, we agreed that ifconfig's behavior was not a bug.  The main
motivation for bin/187551 was to partially resolve kern/187549, but we
resolved kern/187549 in a different way instead.

ObsoleteFiles.inc
etc/mtree/BSD.tests.dist
sbin/ifconfig/tests/fibs_test.sh
sbin/ifconfig/tests/Makefile
sbin/ifconfig/Makefile
	Remove /usr/tests/sbin/ifconfig

PR:		bin/187551
MFC after:	3 days
Sponsored by:	Spectra Logic
2014-05-05 19:38:29 +00:00
marius
ed48e9a0db Allow GEOM_VINUM to be statically compiled into the kernel.
Submitted by:	gleb
MFC after:	3 days
2014-05-02 23:23:18 +00:00
pfg
0681f0fd55 Small cleanup: mostly whitespace vs. tabs. 2014-04-30 21:19:46 +00:00
emaste
f2b36dcede Correct min/max cluster counts for FAT12/16/32
FAT12      1..4084
FAT16   4085..65524
FAT32  65525..

This is required for interoperability with other FAT implementations,
and in particular UEFI.

Obtained from:      NetBSD
Sponsored by:       The FreeBSD Foundation
2014-04-24 20:53:09 +00:00
smh
0c70f2535b Add information about supported NCQ functionality to camcontrol identify.
MFC after:	2 weeks
2014-04-24 02:16:23 +00:00
bz
5745e3fab3 When switching variables to flags in r243185 a few cases were missed.
After r263152 this leaves unused variables if route(8) is compiled
without INET support.
Switch the remaining variable accesses to flags and remove now obsolete
variables.

Reviewed by:	glebius
MFC after:	1 week
2014-04-16 12:29:45 +00:00
brueffer
d8b63f3ba1 Add a missing break in option parsing.
CID:		1011452
Found with:	Coverity Prevent(tm)
MFC after:	1 week
2014-04-15 07:37:56 +00:00
brueffer
8ac2dd562f Fix double fclose() in an error case.
CID:		1006120
Found with:	Coverity Prevent(tm)
MFC after:	1 week
2014-04-14 21:44:34 +00:00
imp
857dd5f125 In tree makefile shouldn't be setting policy piecemeal. Don't set
NO_MANCOMPRESS here.
2014-04-13 05:22:22 +00:00
imp
c39e6fc2c9 NO_MAN= has been deprecated in favor of MAN= for some time, go ahead
and finish the job. ncurses is now the only Makefile in the tree that
uses it since it wasn't a simple mechanical change, and will be
addressed in a future commit.
2014-04-13 05:21:56 +00:00
delphij
727357321c Detach from controlling session of parent. This is similar
to what is done in daemon(3), which we can not use directly
in this context.

Reviewed by:	pjd
MFC after:	2 weeks
2014-04-03 22:14:18 +00:00
ae
f61f9c0347 Document more parition types.
Requested by:	glebius
MFC after:	1 week
2014-04-02 11:12:48 +00:00
jmmv
4dc52363bb Fix path to the run.pl script to let these tests run.
Submitted by:	Peel, Casey
Obtained from:	freebsd-testing
2014-03-27 13:15:22 +00:00
dim
905ed8bc75 Add a SUBDIR_PARALLEL option to bsd.subdir.mk, to allow make to process
all the SUBDIR entries in parallel, instead of serially.  Apply this
option to a selected number of Makefiles, which can greatly speed up the
build on multi-core machines, when using make -j.

This can be extended to more Makefiles later on, whenever they are
verified to work correctly with parallel building.

I tested this on a 24-core machine, with make -j48 buildworld (N = 6):

                before    stddev       after    stddev
                =======   ======       =======  ======
real time        1741.1     16.5         959.8     2.7
user time       12468.7     16.4       14393.0    16.8
sys  time        1825.0     54.8        2110.6    22.8

(user+sys)/real     8.2                   17.1

E.g. the build was approximately 45% faster in real time.  On machines
with less cores, or with lower -j settings, the speedup will not be as
impressive.  But at least you can now almost max out a machine with
buildworld!

Submitted by:	jilles
MFC after:	2 weeks
2014-03-26 22:30:38 +00:00
dim
d8bb143013 Revert r263694, and apply a better fix to squelch unnecessary warnings
from clang about possible keywords being treated as identifiers for the
remainder of the translation unit (a.k.a. -Wkeyword-compat), when using
libstdc++ in combination with -Wsystem-headers.  This will not only fix
devd, but any C++ program using libstdc++.

MFC after:	3 days
X-MFC-With:	r263694
2014-03-26 19:31:33 +00:00
mjg
00964cfdfb Update userspace users of hw.bus.devctl_disable.
This fixes breakage resulting from r263754.

Reported by:	AN <andy@neu.net>
Reviewed by:	imp
Pointy hat to:	me
2014-03-26 02:25:40 +00:00
dim
64e77380a7 Apply a temporary band-aid for building devd with clang 3.4, libstdc++
and -Wsystem-headers enabled (which is the default for any non-zero
WARNS level, crazily enough!).  This is primarily meant to be MFC'd as
soon as possible.

MFC after:	3 days
2014-03-24 20:30:39 +00:00