Commit Graph

315 Commits

Author SHA1 Message Date
Robert Watson
eddfbb763d Build on Jeff Roberson's linker-set based dynamic per-CPU allocator
(DPCPU), as suggested by Peter Wemm, and implement a new per-virtual
network stack memory allocator.  Modify vnet to use the allocator
instead of monolithic global container structures (vinet, ...).  This
change solves many binary compatibility problems associated with
VIMAGE, and restores ELF symbols for virtualized global variables.

Each virtualized global variable exists as a "reference copy", and also
once per virtual network stack.  Virtualized global variables are
tagged at compile-time, placing the in a special linker set, which is
loaded into a contiguous region of kernel memory.  Virtualized global
variables in the base kernel are linked as normal, but those in modules
are copied and relocated to a reserved portion of the kernel's vnet
region with the help of a the kernel linker.

Virtualized global variables exist in per-vnet memory set up when the
network stack instance is created, and are initialized statically from
the reference copy.  Run-time access occurs via an accessor macro, which
converts from the current vnet and requested symbol to a per-vnet
address.  When "options VIMAGE" is not compiled into the kernel, normal
global ELF symbols will be used instead and indirection is avoided.

This change restores static initialization for network stack global
variables, restores support for non-global symbols and types, eliminates
the need for many subsystem constructors, eliminates large per-subsystem
structures that caused many binary compatibility issues both for
monitoring applications (netstat) and kernel modules, removes the
per-function INIT_VNET_*() macros throughout the stack, eliminates the
need for vnet_symmap ksym(2) munging, and eliminates duplicate
definitions of virtualized globals under VIMAGE_GLOBALS.

Bump __FreeBSD_version and update UPDATING.

Portions submitted by:  bz
Reviewed by:            bz, zec
Discussed with:         gnn, jamie, jeff, jhb, julian, sam
Suggested by:           peter
Approved by:            re (kensmith)
2009-07-14 22:48:30 +00:00
Robert Watson
6c7ffe9340 Break at_ifawithnet() into two variants:
- at_ifawithnet(), which acquires an locks it needs and returns an
  at_ifaddr reference.
- at_ifawithnet_locked(), which relies on the caller locking
  at_ifaddr_list, and returns a pointer rather than a reference.

Update various consumers to prefer one or the other, including ether
and fddi output, to properly release at_ifaddr references.

Rework at_control() to manage locking and references in a manner
identical to in_control().

MFC after:	6 weeks
2009-06-24 10:32:44 +00:00
Bjoern A. Zeeb
259d2d5431 carp(4) allows people to share a set of IP addresses and can only
use IPv4/v6 for inter-node communication (according to my reading).

Properly wrap the carp callouts in INET || INET6 and refelect this
in sys/conf/files as well.  While in theory this should be ok,
it might be a bit optimistic to think that carp could build with
inet6 only[1].

Discussed with:		mlaier [1]
2009-06-11 10:26:38 +00:00
Oleg Bulyzhin
dda10d624c Close long existed race with net.inet.ip.fw.one_pass = 0:
If packet leaves ipfw to other kernel subsystem (dummynet, netgraph, etc)
it carries pointer to matching ipfw rule. If this packet then reinjected back
to ipfw, ruleset processing starts from that rule. If rule was deleted
meanwhile, due to existed race condition panic was possible (as well as
other odd effects like parsing rules in 'reap list').

P.S. this commit changes ABI so userland ipfw related binaries should be
recompiled.

MFC after:	1 month
Tested by:	Mikolaj Golub
2009-06-09 21:27:11 +00:00
Bjoern A. Zeeb
8d8bc0182e After r193232 rt_tables in vnet.h are no longer indirectly dependent on
the ROUTETABLES kernel option thus there is no need to include opt_route.h
anymore in all consumers of vnet.h and no longer depend on it for module
builds.

Remove the hidden include in flowtable.h as well and leave the two
explicit #includes in ip_input.c and ip_output.c.
2009-06-08 19:57:35 +00:00
Robert Watson
bcf11e8d00 Move "options MAC" from opt_mac.h to opt_global.h, as it's now in GENERIC
and used in a large number of files, but also because an increasing number
of incorrect uses of MAC calls were sneaking in due to copy-and-paste of
MAC-aware code without the associated opt_mac.h include.

Discussed with:	pjd
2009-06-05 14:55:22 +00:00
Luigi Rizzo
115a40c7bf More cleanup in preparation of ipfw relocation (no actual code change):
+ move ipfw and dummynet hooks declarations to raw_ip.c (definitions
  in ip_var.h) same as for most other global variables.
  This removes some dependencies from ip_input.c;

+ remove the IPFW_LOADED macro, just test ip_fw_chk_ptr directly;

+ remove the DUMMYNET_LOADED macro, just test ip_dn_io_ptr directly;

+ move ip_dn_ruledel_ptr to ip_fw2.c which is the only file using it;

To be merged together with rev 193497

MFC after:	5 days
2009-06-05 13:44:30 +00:00
Marko Zec
21ca7b57bd Change the curvnet variable from a global const struct vnet *,
previously always pointing to the default vnet context, to a
dynamically changing thread-local one.  The currvnet context
should be set on entry to networking code via CURVNET_SET() macros,
and reverted to previous state via CURVNET_RESTORE().  Recursions
on curvnet are permitted, though strongly discuouraged.

This change should have no functional impact on nooptions VIMAGE
kernel builds, where CURVNET_* macros expand to whitespace.

The curthread->td_vnet (aka curvnet) variable's purpose is to be an
indicator of the vnet context in which the current network-related
operation takes place, in case we cannot deduce the current vnet
context from any other source, such as by looking at mbuf's
m->m_pkthdr.rcvif->if_vnet, sockets's so->so_vnet etc.  Moreover, so
far curvnet has turned out to be an invaluable consistency checking
aid: it helps to catch cases when sockets, ifnets or any other
vnet-aware structures may have leaked from one vnet to another.

The exact placement of the CURVNET_SET() / CURVNET_RESTORE() macros
was a result of an empirical iterative process, whith an aim to
reduce recursions on CURVNET_SET() to a minimum, while still reducing
the scope of CURVNET_SET() to networking only operations - the
alternative would be calling CURVNET_SET() on each system call entry.
In general, curvnet has to be set in three typicall cases: when
processing socket-related requests from userspace or from within the
kernel; when processing inbound traffic flowing from device drivers
to upper layers of the networking stack, and when executing
timer-driven networking functions.

This change also introduces a DDB subcommand to show the list of all
vnet instances.

Approved by:	julian (mentor)
2009-05-05 10:56:12 +00:00
Kip Macy
279aa3d419 Change if_output to take a struct route as its fourth argument in order
to allow passing a cached struct llentry * down to L2

Reviewed by:	rwatson
2009-04-16 20:30:28 +00:00
Bjoern A. Zeeb
33553d6e99 For all files including net/vnet.h directly include opt_route.h and
net/route.h.

Remove the hidden include of opt_route.h and net/route.h from net/vnet.h.

We need to make sure that both opt_route.h and net/route.h are included
before net/vnet.h because of the way MRT figures out the number of FIBs
from the kernel option. If we do not, we end up with the default number
of 1 when including net/vnet.h and array sizes are wrong.

This does not change the list of files which depend on opt_route.h
but we can identify them now more easily.
2009-02-27 14:12:05 +00:00
Randall Stewart
2f4afd2125 Adds support for SCTP checksum offload. This means
we, like TCP and UDP, move the checksum calculation
into the IP routines when there is no hardware support
we call into the normal SCTP checksum routine.

The next round of SCTP updates will use
this functionality. Of course the IGB driver needs
a few updates to support the new intel controller set
that actually does SCTP csum offload too.

Reviewed by:	gnn, rwatson, kmacy
2009-02-03 11:00:43 +00:00
Qing Li
9928dafbb8 Remove the rt argument from nd6_storelladdr() because
rt is no longer accessed.
2008-12-17 10:27:34 +00:00
Qing Li
6e6b3f7cbc This main goals of this project are:
1. separating L2 tables (ARP, NDP) from the L3 routing tables
2. removing as much locking dependencies among these layers as
   possible to allow for some parallelism in the search operations
3. simplify the logic in the routing code,

The most notable end result is the obsolescent of the route
cloning (RTF_CLONING) concept, which translated into code reduction
in both IPv4 ARP and IPv6 NDP related modules, and size reduction in
struct rtentry{}. The change in design obsoletes the semantics of
RTF_CLONING, RTF_WASCLONE and RTF_LLINFO routing flags. The userland
applications such as "arp" and "ndp" have been modified to reflect
those changes. The output from "netstat -r" shows only the routing
entries.

Quite a few developers have contributed to this project in the
past: Glebius Smirnoff, Luigi Rizzo, Alessandro Cerri, and
Andre Oppermann. And most recently:

- Kip Macy revised the locking code completely, thus completing
  the last piece of the puzzle, Kip has also been conducting
  active functional testing
- Sam Leffler has helped me improving/refactoring the code, and
  provided valuable reviews
- Julian Elischer setup the perforce tree for me and has helped
  me maintaining that branch before the svn conversion
2008-12-15 06:10:57 +00:00
Marko Zec
385195c062 Conditionally compile out V_ globals while instantiating the appropriate
container structures, depending on VIMAGE_GLOBALS compile time option.

Make VIMAGE_GLOBALS a new compile-time option, which by default will not
be defined, resulting in instatiations of global variables selected for
V_irtualization (enclosed in #ifdef VIMAGE_GLOBALS blocks) to be
effectively compiled out.  Instantiate new global container structures
to hold V_irtualized variables: vnet_net_0, vnet_inet_0, vnet_inet6_0,
vnet_ipsec_0, vnet_netgraph_0, and vnet_gif_0.

Update the VSYM() macro so that depending on VIMAGE_GLOBALS the V_
macros resolve either to the original globals, or to fields inside
container structures, i.e. effectively

#ifdef VIMAGE_GLOBALS
#define V_rt_tables rt_tables
#else
#define V_rt_tables vnet_net_0._rt_tables
#endif

Update SYSCTL_V_*() macros to operate either on globals or on fields
inside container structs.

Extend the internal kldsym() lookups with the ability to resolve
selected fields inside the virtualization container structs.  This
applies only to the fields which are explicitly registered for kldsym()
visibility via VNET_MOD_DECLARE() and vnet_mod_register(), currently
this is done only in sys/net/if.c.

Fix a few broken instances of MODULE_GLOBAL() macro use in SCTP code,
and modify the MODULE_GLOBAL() macro to resolve to V_ macros, which in
turn result in proper code being generated depending on VIMAGE_GLOBALS.

De-virtualize local static variables in sys/contrib/pf/net/pf_subr.c
which were prematurely V_irtualized by automated V_ prepending scripts
during earlier merging steps.  PF virtualization will be done
separately, most probably after next PF import.

Convert a few variable initializations at instantiation to
initialization in init functions, most notably in ipfw.  Also convert
TUNABLE_INT() initializers for V_ variables to TUNABLE_FETCH_INT() in
initializer functions.

Discussed at:	devsummit Strassburg
Reviewed by:	bz, julian
Approved by:	julian (mentor)
Obtained from:	//depot/projects/vimage-commit2/...
X-MFC after:	never
Sponsored by:	NLnet Foundation, The FreeBSD Foundation
2008-12-10 23:12:39 +00:00
Bjoern A. Zeeb
4b79449e2f Rather than using hidden includes (with cicular dependencies),
directly include only the header files needed. This reduces the
unneeded spamming of various headers into lots of files.

For now, this leaves us with very few modules including vnet.h
and thus needing to depend on opt_route.h.

Reviewed by:	brooks, gnn, des, zec, imp
Sponsored by:	The FreeBSD Foundation
2008-12-02 21:37:28 +00:00
Kip Macy
aea78d2094 convert calls to IFQ_HANDOFF to if_transmit 2008-11-22 07:35:45 +00:00
Marko Zec
44e33a0758 Change the initialization methodology for global variables scheduled
for virtualization.

Instead of initializing the affected global variables at instatiation,
assign initial values to them in initializer functions.  As a rule,
initialization at instatiation for such variables should never be
introduced again from now on.  Furthermore, enclose all instantiations
of such global variables in #ifdef VIMAGE_GLOBALS blocks.

Essentialy, this change should have zero functional impact.  In the next
phase of merging network stack virtualization infrastructure from
p4/vimage branch, the new initialization methology will allow us to
switch between using global variables and their counterparts residing in
virtualization containers with minimum code churn, and in the long run
allow us to intialize multiple instances of such container structures.

Discussed at:	devsummit Strassburg
Reviewed by:	bz, julian
Approved by:	julian (mentor)
Obtained from:	//depot/projects/vimage-commit2/...
X-MFC after:	never
Sponsored by:	NLnet Foundation, The FreeBSD Foundation
2008-11-19 09:39:34 +00:00
Dag-Erling Smørgrav
1ede983cc9 Retire the MALLOC and FREE macros. They are an abomination unto style(9).
MFC after:	3 months
2008-10-23 15:53:51 +00:00
Marko Zec
8b615593fc Step 1.5 of importing the network stack virtualization infrastructure
from the vimage project, as per plan established at devsummit 08/08:
http://wiki.freebsd.org/Image/Notes200808DevSummit

Introduce INIT_VNET_*() initializer macros, VNET_FOREACH() iterator
macros, and CURVNET_SET() context setting macros, all currently
resolving to NOPs.

Prepare for virtualization of selected SYSCTL objects by introducing a
family of SYSCTL_V_*() macros, currently resolving to their global
counterparts, i.e. SYSCTL_V_INT() == SYSCTL_INT().

Move selected #defines from sys/sys/vimage.h to newly introduced header
files specific to virtualized subsystems (sys/net/vnet.h,
sys/netinet/vinet.h etc.).

All the changes are verified to have zero functional impact at this
point in time by doing MD5 comparision between pre- and post-change
object files(*).

(*) netipsec/keysock.c did not validate depending on compile time options.

Implemented by:	julian, bz, brooks, zec
Reviewed by:	julian, bz, brooks, kris, rwatson, ...
Approved by:	julian (mentor)
Obtained from:	//depot/projects/vimage-commit2/...
X-MFC after:	never
Sponsored by:	NLnet Foundation, The FreeBSD Foundation
2008-10-02 15:37:58 +00:00
Ed Maste
d54d93ac7f Move CTASSERT of ether header sizes out of the header file and into
if_ethersubr.c.  CTASSERT is implemented using a dummy typedef, which if
used in a header file may conflict with another CTASSERT in a source file
using that header.

I'll make a note of this in CTASSERT's man page.

Approved by:	imp
2008-08-27 17:10:37 +00:00
Bjoern A. Zeeb
603724d3ab Commit step 1 of the vimage project, (network stack)
virtualization work done by Marko Zec (zec@).

This is the first in a series of commits over the course
of the next few weeks.

Mark all uses of global variables to be virtualized
with a V_ prefix.
Use macros to map them back to their global names for
now, so this is a NOP change only.

We hope to have caught at least 85-90% of what is needed
so we do not invalidate a lot of outstanding patches again.

Obtained from:	//depot/projects/vimage-commit2/...
Reviewed by:	brooks, des, ed, mav, julian,
		jamie, kris, rwatson, zec, ...
		(various people I forgot, different versions)
		md5 (with a bit of help)
Sponsored by:	NLnet Foundation, The FreeBSD Foundation
X-MFC after:	never
V_Commit_Message_Reviewed_By:	more people than the patch
2008-08-17 23:27:27 +00:00
Antoine Brodin
933dad75e3 Add missing braces in #if 0ed code.
Approved by:	rwatson (mentor)
MFC after:	1 month
2008-05-10 18:33:38 +00:00
Julian Elischer
6eeac1d921 Add an option (compiled out by default)
to profile outoing packets for a number of mbuf chain
related parameters
e.g. number of mbufs, wasted space.
probably will do with further work later.

Reviewed by: various
2008-04-29 21:23:21 +00:00
Kip Macy
879773c18b back out last change as Sam believes that it breaks multicast - need to revisit after following up with pyun 2008-03-20 06:19:34 +00:00
Kip Macy
83631568fe Don't re-initialize the interface if it is already running.
This one line change makes the following code found in many ethernet device drivers
(at least em, igb, ixgbe, and cxgb) gratuitous

	case SIOCSIFADDR:
		if (ifa->ifa_addr->sa_family == AF_INET) {
			/*
			 * XXX
			 * Since resetting hardware takes a very long time
			 * and results in link renegotiation we only
			 * initialize the hardware only when it is absolutely
			 * required.
			 */
			ifp->if_flags |= IFF_UP;
			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
				EM_CORE_LOCK(adapter);
				em_init_locked(adapter);
				EM_CORE_UNLOCK(adapter);
			}
			arp_ifinit(ifp, ifa);
		} else
			error = ether_ioctl(ifp, command, data);
		break;
2008-03-20 05:35:02 +00:00
Robert Watson
b9175c4556 Move IFF_NEEDSGIANT warning from if_ethersubr.c to if.c so it is displayed
for all network interfaces, not just ethernet-like ones.

Upgrade it to a louder WARNING and be explicit that the flag is obsolete.
Support for IFF_NEEDSGIANT will be removed in a few months (see arch@ for
details) and will not appear in 8.0.

Upgrade if_watchdog to a WARNING.
2008-03-07 16:00:44 +00:00
Oleg Bulyzhin
897c0f57d4 1) dummynet_io() declaration has changed.
2) Alter packet flow inside dummynet: allow certain packets to bypass
dummynet scheduler. Benefits are:

- lower latency: if packet flow does not exceed pipe bandwidth, packets
  will not be (up to tick) delayed (due to dummynet's scheduler granularity).
- lower overhead: if packet avoids dummynet scheduler it shouldn't reenter ip
  stack later. Such packets can be fastforwarded.
- recursion (which can lead to kernel stack exhaution) eliminated. This fix
  long existed panic, which can be triggered this way:
  	kldload dummynet
	sysctl net.inet.ip.fw.one_pass=0
	ipfw pipe 1 config bw 0
	for i in `jot 30`; do ipfw add 1 pipe 1 icmp from any to any; done
	ping -c 1 localhost

3) Three new sysctl nodes are added:
net.inet.ip.dummynet.io_pkt -		packets passed to dummynet
net.inet.ip.dummynet.io_pkt_fast - 	packets avoided dummynet scheduler
net.inet.ip.dummynet.io_pkt_drop -	packets dropped by dummynet

P.S. Above comments are true only for layer 3 packets. Layer 2 packet flow
     is not changed yet.

MFC after:	3 month
2007-11-06 23:01:42 +00:00
Robert Watson
30d239bc4c Merge first in a series of TrustedBSD MAC Framework KPI changes
from Mac OS X Leopard--rationalize naming for entry points to
the following general forms:

  mac_<object>_<method/action>
  mac_<object>_check_<method/action>

The previous naming scheme was inconsistent and mostly
reversed from the new scheme.  Also, make object types more
consistent and remove spaces from object types that contain
multiple parts ("posix_sem" -> "posixsem") to make mechanical
parsing easier.  Introduce a new "netinet" object type for
certain IPv4/IPv6-related methods.  Also simplify, slightly,
some entry point names.

All MAC policy modules will need to be recompiled, and modules
not updates as part of this commit will need to be modified to
conform to the new KPI.

Sponsored by:	SPARTA (original patches against Mac OS X)
Obtained from:	TrustedBSD Project, Apple Computer
2007-10-24 19:04:04 +00:00
Andrew Thompson
a0cf818670 Use a uint16_t type for the vlan tag rather an int. 2007-10-18 21:52:31 +00:00
Andrew Thompson
60e87ca8df The bridging output function puts the mbuf directly on the interfaces send
queue so the output network card must support the same tagging mechanism as
how the frame was input (prepended Ethernet header tag or stripped HW mflag).

Now the vlan Ethernet header is _always_ stripped in ether_input and the mbuf
flagged, only only network cards with VLAN_HWTAGGING enabled would properly
re-tag any outgoing vlan frames.

If the outgoing interface does not support hardware tagging then readd the vlan
header to the front of the frame. Move the common vlan encapsulation in to
ether_vlanencap().

Reported by:	Erik Osterholm, Jon Otterholm
MFC after:	1 week
2007-10-18 21:22:15 +00:00
Julian Elischer
d3a31a9562 Remove DIAG code that discards oversized packets.
There has been general consensus that this was a bad idea/

Approved by:    re (bmah)
2007-09-14 06:57:28 +00:00
Robert Watson
33d2bb9ca3 First in a series of changes to remove the now-unused Giant compatibility
framework for non-MPSAFE network protocols:

- Remove debug_mpsafenet variable, sysctl, and tunable.
- Remove NET_NEEDS_GIANT() and associate SYSINITSs used by it to force
  debug.mpsafenet=0 if non-MPSAFE protocols are compiled into the kernel.
- Remove logic to automatically flag interrupt handlers as non-MPSAFE if
  debug.mpsafenet is set for an INTR_TYPE_NET handler.
- Remove logic to automatically flag netisr handlers as non-MPSAFE if
  debug.mpsafenet is set.
- Remove references in a few subsystems, including NFS and Cronyx drivers,
  which keyed off debug_mpsafenet to determine various aspects of their own
  locking behavior.
- Convert NET_LOCK_GIANT(), NET_UNLOCK_GIANT(), and NET_ASSERT_GIANT into
  no-op's, as their entire behavior was determined by the value in
  debug_mpsafenet.
- Alias NET_CALLOUT_MPSAFE to CALLOUT_MPSAFE.

Many remaining references to NET_.*_GIANT() and NET_CALLOUT_MPSAFE are still
present in subsystems, and will be removed in followup commits.

Reviewed by:	bz, jhb
Approved by:	re (kensmith)
2007-07-27 11:59:57 +00:00
Max Laier
60ee384760 Link pf 4.1 to the build:
- move ftp-proxy from libexec to usr.sbin
 - add tftp-proxy
 - new altq mtag link

Approved by:	re (kensmith)
2007-07-03 12:46:08 +00:00
Andrew Gallatin
ead7661da1 Use if_capenable to allow LRO enabled drivers to bypass
the MTU check in ether_input().
2007-06-12 19:53:44 +00:00
Andrew Gallatin
2144e288fa Move the oversize ethernet frame size check into DIAGNOSTIC,
as was proposed when it was originally added.  This allows
LRO to work on non-DIAGNOSTIC kernels without consuming
any mbuf flags.

Discussed with: sam
2007-06-11 18:45:49 +00:00
Andrew Gallatin
56b8f0b02d Back out the previous commit which added an M_LRO mbuf flag
to defeat the mtu check in ether_input.  Mbuf flags are too scarce.
Discussed with: sam
2007-06-11 18:26:25 +00:00
Andrew Gallatin
b6af0abdc4 Allow drivers, such as cxgb and mxge, which support LRO to bypass
the MTU check in ether_input() on LRO merged frames.

Discussed with: kmacy
2007-06-11 14:59:56 +00:00
Yaroslav Tykhiy
995c7fd1bf Sync ether_ioctl() with ioctl(2) and ifnet.if_ioctl
as to the type of the command argument: int -> u_long.
These types have different widths in the 64-bit world.

Add a note to UPDATING because the change breaks KBI
on 64-bit platforms.

Discussed on:	-net, -current
Reviewed by:	bms, ru
2007-05-29 12:40:45 +00:00
Andrew Thompson
18242d3b09 Rename the trunk(4) driver to lagg(4) as it is too similar to vlan trunking.
The name trunk is misused as the networking term trunk means carrying multiple
VLANs over a single connection. The IEEE standard for link aggregation (802.3
section 3) does not talk about 'trunk' at all while it is used throughout IEEE
802.1Q in describing vlans.

The lagg(4) driver provides link aggregation, failover and fault tolerance.

Discussed on:	current@
2007-04-17 00:35:11 +00:00
Andrew Thompson
b47888ceba Add the trunk(4) driver for providing link aggregation, failover and fault
tolerance.  This driver allows aggregation of multiple network interfaces as
one virtual interface using a number of different protocols/algorithms.

failover    - Sends traffic through the secondary port if the master becomes
              inactive.
fec         - Supports Cisco Fast EtherChannel.
lacp        - Supports the IEEE 802.3ad Link Aggregation Control Protocol
              (LACP) and the Marker Protocol.
loadbalance - Static loadbalancing using an outgoing hash.
roundrobin  - Distributes outgoing traffic using a round-robin scheduler
              through all active ports.

This code was obtained from OpenBSD and this also includes 802.3ad LACP support
from agr(4) in NetBSD.
2007-04-10 00:27:25 +00:00
Bruce M Simpson
e7f8c8339c Fix a typo, and update a comment.
Submitted by:	yar
2007-03-22 19:08:39 +00:00
Bruce M Simpson
402d5e2755 Make the m_pullup() diagnostic message compile-time conditional on DIAGNOSTIC.
Requested by:	glebius
2007-03-20 14:29:54 +00:00
Bruce M Simpson
69462a8297 Clean up the ether_input() path by using the M_PROMISC flag.
Main points of this change:
 * Drop frames immediately if the interface is not marked IFF_UP.
 * Always trim off the frame checksum if present.
 * Always use M_VLANTAG in preference to passing 802.1Q frames
   to consumers.
 * Use __func__ consistently for KASSERT().
 * Use the M_PROMISC flag to detect situations where ether_input()
   may reenter itself on the same call graph with the same mbuf which
   was promiscuously received on behalf of subsystems such as
   netgraph, carp, and vlan.
 * 802.1P frames (that is, VLAN frames with an ID of 0) will now be
   passed to layer 3 input paths.
 * Deal with the special case for CARP in a sane way.

This is a significant rewrite of code on the critical path. Please report
any issues to me if they arise. Frames will now only pass through dummynet
if M_PROMISC is cleared, to avoid problems with re-entry.

The handling of CARP needs to be revisited architecturally. The M_PROMISC
flag may potentially be demoted to a link-layer flag only as it is in
NetBSD, where the idea originated.

Discussed on:	net
Idea from:	NetBSD
Reviewed by:	yar
MFC after:	1 month
2007-03-19 18:39:36 +00:00
Christian S.J. Peron
d05d46160a Use ETHER_BPF_MTAP() instead of BPF_MTAP() here. It's possible
incoming packets have had their 802.1Q tags processed by the
hardware, resulting in them being stripped from the packets, and
placed on the mbuf.  This fixes the processing of 802.1Q tags when
hardware offload of 802.1Q tags is enabled.
2007-02-22 14:50:31 +00:00
Yaroslav Tykhiy
9983b3c02d Note that rev. 1.221 introduced a local workaround for a general problem.
Add a pointer to the relevant PR for future reference.  The whole comment
will be OK to remove as soon as the general solution is applied.

PR:	kern/105943
2006-12-24 08:52:13 +00:00
Luigi Rizzo
294dd290c6 Fix an oscure bug triggered by a recent change in kern_socket.c.
The symptoms were that outgoing DHCP requests for diskless kernels
had the IP header corrupt. After long investigations, the source of
the problem was found in ether_output() - for SIMPLEX interfaces
and broadcast traffic, a copy of the packet is passed back to the kernel
through if_simloop(). However if_simloop() modifies the mbuf, while
the copy obtained through m_copym() is a readonly one.

The bug has been there forever, but it has been triggered only recently
by a change in sosend_dgram() which passed down mbufs with sufficient
space to prepend the header.

This fix is trivial - use m_dup() instead of m_copy() to create
the copy. As an alternative, we could try and modify if_simloop()
to play safely with readonly mbufs, but i don't think it is worthwhile
because 1) this is a relatively infrequent code path so we do not need
to worry too much about performance, and 2) the cost of doing an
extra m_pullup in if_simloop() is probably the same as doing the
copy of the cluster, anyways.

MFC after: 1 week
2006-12-08 10:36:45 +00:00
Christian S.J. Peron
52f1277eea Currently, drivers that support hardware offload of VLAN tag
processing are forced to toggle this functionality when the card
is put in and out of promiscuous mode.  The main reason for this
is because the hardware strips the VLAN tag, making it impossible
for the tag information to show up in network diagnostic tools like
tcpdump(1).

This change introduces ether_vlan_mtap(), which is called if the
mbuf has M_VLANTAG set.  VLAN information is extracted from the
mbuf and inserted into a stack allocated ether vlan header which
is then inserted through the bpf machinery via bpf_mtap2(). The
original mbuf's data pointer and lengths are temporarily adjusted
to eliminate the original Ethernet header for the duration of the
tap operation. This should have no long term effects on the mbuf.

Also, define a new macro, ETHER_BPF_MTAP which should be used
by drivers which support hardware offload of VLAN tag processing.

The fixes for the relevant drivers will follow shortly.

Discussed with:		rwatson, andre, jhb (and others)
Much feedback from:	sam, ru
MFC after:	1 month [1]

[1] The version that is eventually MFCed will be somewhat
    different then this, as there has been significant work
    done to the VLAN code in HEAD.
2006-11-18 23:17:22 +00:00
Robert Watson
aed5570872 Complete break-out of sys/sys/mac.h into sys/security/mac/mac_framework.h
begun with a repo-copy of mac.h to mac_framework.h.  sys/mac.h now
contains the userspace and user<->kernel API and definitions, with all
in-kernel interfaces moved to mac_framework.h, which is now included
across most of the kernel instead.

This change is the first step in a larger cleanup and sweep of MAC
Framework interfaces in the kernel, and will not be MFC'd.

Obtained from:	TrustedBSD Project
Sponsored by:	SPARTA
2006-10-22 11:52:19 +00:00
Andrew Thompson
3f7d13964e Move the bridge hook after the loopback check so that IFF_SIMPLEX is honoured
on member interfaces. This makes us the same as OpenBSD/NetBSD.

MFC after:	3 days
2006-08-25 20:16:39 +00:00
Andrew Thompson
9674cf0e27 Remove the dependency of bridgestp.h on if_bridgevar.h by moving a couple of
private structures to if_bridge.c.
2006-07-27 21:01:48 +00:00
Tai-hwa Liang
da87ff8633 Fixing compilation bustage: net/if_bridgevar.h depends on net/bridgestp.h. 2006-07-27 03:50:38 +00:00
Christian S.J. Peron
de572b371b Unbreak byte counters when network interfaces are in monitor mode by
re-organizing the monitor return logic. We perform interface monitoring
checks after we have determined if the CRC is still on the packet, if
it is, m_adj() is called which will adjust the packet length. This
ensures that we are not including CRC lengths in the byte counters for
each packet.

Discussed with:	andre, glebius
2006-03-03 17:21:08 +00:00
Oleg Bulyzhin
3ecf1851df Properly initialize args structure before passing it to ipfw_chk(): having
uninitialized args.inp is unhealthy for uid/gid/jail ipfw rules.

PR:		kern/92589
Approved by:	glebius (mentor)
MFC after:	1 week
2006-02-03 23:03:07 +00:00
Gleb Smirnoff
75ee267c22 Merge the //depot/user/yar/vlan branch into CVS. It contains some collective
work by yar, thompsa and myself. The checksum offloading part also involves
work done by Mihail Balikov.

The most important changes:

o   Instead of global linked list of all vlan softc use a per-trunk
  hash. The size of hash is dynamically adjusted, depending on
  number of entries. This changes struct ifnet, replacing counter
  of vlans with a pointer to trunk structure. This change is an
  improvement for setups with big number of VLANs, several interfaces
  and several CPUs. It is a small regression for a setup with a single
  VLAN interface.
    An alternative to dynamic hash is a per-trunk static array with
  4096 entries, which is a compile time option - VLAN_ARRAY. In my
  experiments the array is not an improvement, probably because such
  a big trunk structure doesn't fit into CPU cache.
o   Introduce an UMA zone for VLAN tags. Since drivers depend on it,
  the zone is declared in kern_mbuf.c, not in optional vlan(4) driver.
  This change is a big improvement for any setup utilizing vlan(4).
o   Use rwlock(9) instead of mutex(9) for locking. We are the first
  ones to do this! :)
o   Some drivers can do hardware VLAN tagging + hardware checksum
  offloading. Add an infrastructure for this. Whenever vlan(4) is
  attached to a parent or parent configuration is changed, the flags
  on vlan(4) interface are updated.

In collaboration with:	yar, thompsa
In collaboration with:	Mihail Balikov <mihail.balikov interbgc.com>
2006-01-30 13:45:15 +00:00
Andre Oppermann
5d691e6da8 Return mbuf pointer or NULL from ip_fastforward() as the mbuf pointer
may have changed by m_pullup() during fastforward processing.

While this is a bug it is actually never triggered in real world
situations and it is not remotely exploitable.

Found by:	Coverity Prevent(tm)
Coverity ID:	CID780
Sponsored by:	TCP/IP Optimization Fundraise 2005
2006-01-18 14:24:39 +00:00
Oleg Bulyzhin
c54c76cc2f 1) remove useless check of loop_copy - corresponding code was removed in
rev. 1.70 five years ago.
2) convert loop_copy to "non-negative" flag

Approved by:	glebius (mentor)
MFC after:	2 weeks
2005-12-22 12:16:20 +00:00
Andrew Thompson
e0a87e8acd Change from a callback in if_ethersubr to using EVENTHANDLER in order to detach
span ports when they disappear. The span port does not have a pointer to the
softc so revert r1.31 and bring back the softc linked-list.

MFC after:	2 weeks
2005-12-17 06:33:51 +00:00
Andre Oppermann
147f74d176 Purge layer specific mbuf flags on layer crossings to avoid confusing
upper or lower layers.

Sponsored by:	TCP/IP Optimization Fundraise 2005
2005-11-18 16:23:26 +00:00
Ruslan Ermilov
4a0d6638b3 - Store pointer to the link-level address right in "struct ifnet"
rather than in ifindex_table[]; all (except one) accesses are
  through ifp anyway.  IF_LLADDR() works faster, and all (except
  one) ifaddr_byindex() users were converted to use ifp->if_addr.

- Stop storing a (pointer to) Ethernet address in "struct arpcom",
  and drop the IFP2ENADDR() macro; all users have been converted
  to use IF_LLADDR() instead.
2005-11-11 16:04:59 +00:00
Ruslan Ermilov
d09ed26fd8 - Make IFP2ENADDR() a pointer to IF_LLADDR() rather than another
copy of Ethernet address.

- Change iso88025_ifattach() and fddi_ifattach() to accept MAC
  address as an argument, similar to ether_ifattach(), to make
  this work.
2005-11-11 07:36:14 +00:00
Andrew Thompson
fd6238a659 Further clean up the bridge hooks in if_ethersubr.c and ng_ether.c
- move the function pointer definitions to if_bridgevar.h
- move most of the logic to the new BRIDGE_INPUT and BRIDGE_OUTPUT macros
- remove unneeded functions from if_bridgevar.h and sort a little.
2005-10-14 02:38:47 +00:00
Andrew Thompson
20a65f37a0 From 101 ways to panic your kernel.
Use bridge_ifdetach() to notify the bridge that a member has been detached. The
bridge can then remove it from its interface list and not try to send out via a
dead pointer.
2005-10-13 23:05:55 +00:00
Julian Elischer
d0a2acd430 Consolidate two adjacent conditional blocks
I actually believe the code in question should be elsewhere (in the preceding
function).

MFC after:	1 week
2005-10-13 21:48:27 +00:00
Ruslan Ermilov
199474fd36 Remove a stale comment. 2005-10-13 17:26:14 +00:00
Andrew Thompson
9cff52f7f6 Clean up the if_bridge hooks a bit in if_ethersubr.c and ng_ether.c, move
the broadcast/multicast test to bridge_input().

Requested by:	glebius
2005-10-13 09:43:30 +00:00
Gleb Smirnoff
6512768b89 A deja vu of:
http://lists.freebsd.org/pipermail/cvs-src/2004-October/033496.html

The same problem applies to if_bridge(4), too.

- Copy-and-paste the if_bridge(4) related block from
  if_ethersubr.c to ng_ether.c
- Add XXXs, so that copy-and-paste would be noticed by
  any future editors of this code.
- Also add XXXs near if_bridge(4) declarations.

Silence from:	thompsa
2005-10-07 14:14:47 +00:00
Andrew Thompson
64465c6bd3 Fix KASSERT function name in ether_output, use __func__ while I am here. 2005-10-06 01:21:40 +00:00
Max Laier
b6de9e91bd Remove bridge(4) from the tree. if_bridge(4) is a full functional
replacement and has additional features which make it superior.

Discussed on:	-arch
Reviewed by:	thompsa
X-MFC-after:	never (RELENG_6 as transition period)
2005-09-27 18:10:43 +00:00
Andrew Thompson
59280079d3 Add support for multicast to the bridge and allow inet6 addresses to be
assigned to the interface.

IPv6 auto-configuration is disabled. An IPv6 link-local address has a
link-local scope within one link, the spec is unclear for the bridge case and
it may cause scope violation.

An address can be assigned in the usual way;
  ifconfig bridge0 inet6 xxxx:...

Tested by:	bmah
Reviewed by:	ume (netinet6)
Approved by:	mlaier (mentor)
MFC after:	1 week
2005-09-06 21:11:59 +00:00
Max Laier
0bdf5171c8 Don't loop back packets that have been routed by pf. This fixes an endless
loop where the same packet is sent over and over again.

Obtained from:	OpenBSD
Reported by:	Sergey Lapin
Tested by:	Sergey Lapin
MFC after:	7 days
2005-08-23 14:13:17 +00:00
Robert Watson
13f4c340ae Propagate rename of IFF_OACTIVE and IFF_RUNNING to IFF_DRV_OACTIVE and
IFF_DRV_RUNNING, as well as the move from ifnet.if_flags to
ifnet.if_drv_flags.  Device drivers are now responsible for
synchronizing access to these flags, as they are in if_drv_flags.  This
helps prevent races between the network stack and device driver in
maintaining the interface flags field.

Many __FreeBSD__ and __FreeBSD_version checks maintained and continued;
some less so.

Reviewed by:	pjd, bz
MFC after:	7 days
2005-08-09 10:20:02 +00:00
Robert Watson
09df718e0e When allocating link layer ifnet address list entries in
ifp->if_resolvemulti(), do so with M_NOWAIT rather than M_WAITOK, so
that a mutex can be held over the call.  In the FDDI code, add a
missing M_ZERO.  Consumers are already aware that if_resolvemulti()
can fail.

MFC after:	1 week
2005-08-02 17:52:52 +00:00
Poul-Henning Kamp
514bcb8955 Add some KASSERTS to catch null pointers. 2005-07-21 09:00:51 +00:00
Brooks Davis
fc74a9f93a Stop embedding struct ifnet at the top of driver softcs. Instead the
struct ifnet or the layer 2 common structure it was embedded in have
been replaced with a struct ifnet pointer to be filled by a call to the
new function, if_alloc(). The layer 2 common structure is also allocated
via if_alloc() based on the interface type. It is hung off the new
struct ifnet member, if_l2com.

This change removes the size of these structures from the kernel ABI and
will allow us to better manage them as interfaces come and go.

Other changes of note:
 - Struct arpcom is no longer referenced in normal interface code.
   Instead the Ethernet address is accessed via the IFP2ENADDR() macro.
   To enforce this ac_enaddr has been renamed to _ac_enaddr.
 - The second argument to ether_ifattach is now always the mac address
   from driver private storage rather than sometimes being ac_enaddr.

Reviewed by:	sobomax, sam
2005-06-10 16:49:24 +00:00
Andrew Thompson
c8b0129238 Add dummynet(4) support to if_bridge, this code is largely based on bridge.c.
This is the final piece to match bridge.c in functionality, we can now be a
drop-in replacement.

Approved by:	mlaier (mentor)
2005-06-10 01:25:22 +00:00
Andrew Thompson
5a6530a38d Fix indentation of two comment blocks from the last commit.
Approved by:	mlaier (mentor)
2005-06-05 03:49:23 +00:00
Andrew Thompson
8f86751705 Add hooks into the networking layer to support if_bridge. This changes struct
ifnet so a buildworld is necessary.

Approved by:	mlaier (mentor)
Obtained from:	NetBSD
2005-06-05 03:13:13 +00:00
Maxim Sobolev
a10260280f Fix ef(4) driver when kernel compiled w/o IPX.
MFC after:	3 days
2005-03-06 22:59:40 +00:00
Gleb Smirnoff
58996b1337 Fix long lines in comment introduced in previous commit. 2005-02-24 10:15:50 +00:00
Robert Watson
7e2041e0c4 When prepending an LCC SNAP header to an atalk outgoing ethernet packet,
allocate the additional mbuf (if needed) using a non-sleeping memory
allocation.

MFC after:	7 days
2005-02-22 15:03:25 +00:00
Gleb Smirnoff
a97719482d Add CARP (Common Address Redundancy Protocol), which allows multiple
hosts to share an IP address, providing high availability and load
balancing.

Original work on CARP done by Michael Shalayeff, with many
additions by Marco Pfatschbacher and Ryan McBride.

FreeBSD port done solely by Max Laier.

Patch by:	mlaier
Obtained from:	OpenBSD (mickey, mcbride)
2005-02-22 13:04:05 +00:00
Ruslan Ermilov
6ee20ab521 Allocate the M_VLANTAG m_pkthdr flag, and use it to indicate that
a packet has VLAN mbuf tag attached.  This is faster to check than
m_tag_locate(), and allows us to use the tags in non-vlan(4) VLAN
producers.

The first argument to VLAN_OUTPUT_TAG() is now unused but retained
for backward compatibility.

While here, embellish a fix in rev. 1.174 of if_ethersubr.c -- it
now checks for packets with VLAN (mbuf) tags, and it should now
be possible to bridge(4) on vlan(4)'s whose parent interfaces
support VLAN decapsulation in hardware.

Reviewed by:	sam
2005-02-18 22:31:19 +00:00
Gleb Smirnoff
eb46c866bb Check for non-NULL ac_netgraph field in interface arpcom, instead of
checking global presence of ng_ether(4).

Reviewed by:	ru
2005-02-14 11:58:54 +00:00
Ruslan Ermilov
6c23e6cc5a If no vlan(4) interfaces are configured for the interface, and the
driver did VLAN decapsulation in hardware, we were passing a frame
as if it came for the parent (non-VLAN) interface.  Stop this from
happening.

Reminded by:	glebius
Security:	This could pose a security risk in some setups
2005-02-14 08:29:42 +00:00
Gleb Smirnoff
28935658c4 - Reduce number of arguments passed to dummynet_io(), we already have cookie
in struct ip_fw_args itself.
- Remove redundant &= 0xffff from dummynet_io().
2005-01-16 11:13:18 +00:00
Gleb Smirnoff
6c69a7c30b o Clean up interface between ip_fw_chk() and its callers:
- ip_fw_chk() returns action as function return value. Field retval is
  removed from args structure. Action is not flag any more. It is one
  of integer constants.
- Any action-specific cookies are returned either in new "cookie" field
  in args structure (dummynet, future netgraph glue), or in mbuf tag
  attached to packet (divert, tee, some future action).

o Convert parsing of return value from ip_fw_chk() in ipfw_check_{in,out}()
  to a switch structure, so that the functions are more readable, and a future
  actions can be added with less modifications.

Approved by:	andre
MFC after:	2 months
2005-01-14 09:00:46 +00:00
Warner Losh
c398230b64 /* -> /*- for license, minor formatting changes 2005-01-07 01:45:51 +00:00
Gleb Smirnoff
a176c2aeaf Fix packet flow when both ng_ether(4) and bridge(4) are in use:
- push all bridge logic from if_ethersubr.c into bridge.c
  make bridge_in() return mbuf pointer (or NULL).
- call only bridge_in() from ether_input(), after ng_ether_input()
  was optinally called.
- call bridge_in() from ng_ether_rcv_upper().

Long description:	http://lists.freebsd.org/mailman/htdig/freebsd-net/2004-May/003881.html
Reported by:		Jian-Wei Wang <jwwang at FreeBSD.csie.NCTU.edu.tw>
Tested by:		myself, Sergey Lyubka
Reviewed by:		sam
Approved by:		julian (mentor)
MFC after:		2 months
2004-10-12 10:33:42 +00:00
Robert Watson
acf032f516 When harvesting entropy from an ethernet mbuf, do so before freeing the
mbuf.

RELENG_5 candidate.
2004-10-11 10:21:34 +00:00
Robert Watson
af5e59bf28 Add a new network interface flag, IFF_NEEDSGIANT, which will allow
device drivers to declare that the ifp->if_start() method implemented
by the driver requires Giant in order to operate correctly.

Add a 'struct task' to 'struct ifnet' that can be used to execute a
deferred ifp->if_start() in the event that if_start needs to be called
in a Giant-free environment.  To do this, introduce if_start(), a
wrapper function for ifp->if_start().  If the interface can run MPSAFE,
it directly dispatches into the interface start routine.  If it can't
run MPSAFE, we're running with debug.mpsafenet != 0, and Giant isn't
currently held, the task is queued to execute in a swi holding Giant
via if_start_deferred().

Modify if_handoff() to use if_start() instead of direct dispatch.
Modify 802.11 to use if_start() instead of direct dispatch.

This is intended to provide increased compatibility for non-MPSAFE
network device drivers in the presence of Giant-free operation via
asynchronous dispatch.  However, this commit does not mark any network
interfaces as IFF_NEEDSGIANT.
2004-07-27 23:20:45 +00:00
Bruce M Simpson
086e98c437 Use ETHER_IS_MULTICAST() consistently in ether_resolvemulti().
Reviewed by:	jmallett
2004-07-09 05:26:27 +00:00
Brooks Davis
f93dfa28b1 Don't announce the ethernet address when it's 00:00:00:00:00:00. It's
not of any interest.  This primairly happens when vlan(4) interfaces are
created.
2004-07-02 19:44:59 +00:00
Joerg Wunsch
cd0cd0149b When considering an ethernet frame that is not destined for us, do not
only allow this to be further processed when bridging is active on
that interface, but also if the current packet has a VLAN tag and
VLANs are active on our interface.  This gives the VLAN layers a
chance to also consider the packet (and perhaps drop it instead of the
main dispatcher).

This fixes a situation where bridging was only active on VLAN
interfaces but ether_demux() called on behalf of the main interface
had already thrown the packet away.

MFC after:	4 weeks
2004-06-24 12:31:44 +00:00
Dag-Erling Smørgrav
d7647d966e Make dependencies on the TCP/IP stack conditional on INET / INET6. This
makes it possible to build a kernel with NIC drivers but no TCP/IP stack.

Sponsored by:	Teleplan AS
2004-06-24 10:58:08 +00:00
Max Laier
affc907d0c Replace IF_HANDOFF with new IFQ_HANDOFF to enqueue with ALTQ once enabled on
the respective drivers.
2004-06-15 23:57:42 +00:00
Christian Weisgerber
16b4a34316 Add helper functions to calculate the standard ethernet CRC in
little/big endian fashion, so that network drivers can just reference
the standard implementation and don't have to bring their own.

As discussed on arch@.

Obtained from:	NetBSD
2004-06-02 21:34:14 +00:00
Poul-Henning Kamp
41ee9f1c69 Add some missing <sys/module.h> includes which are masked by the
one on death-row in <sys/kernel.h>
2004-05-30 17:57:46 +00:00
Luigi Rizzo
cd46a114fc This commit does two things:
1. rt_check() cleanup:
    rt_check() is only necessary for some address families to gain access
    to the corresponding arp entry, so call it only in/near the *resolve()
    routines where it is actually used -- at the moment this is
    arpresolve(), nd6_storelladdr() (the call is embedded here),
    and atmresolve() (the call is just before atmresolve to reduce
    the number of changes).
    This change will make it a lot easier to decouple the arp table
    from the routing table.

    There is an extra call to rt_check() in if_iso88025subr.c to
    determine the routing info length. I have left it alone for
    the time being.

    The interface of arpresolve() and nd6_storelladdr() now changes slightly:
     + the 'rtentry' parameter (really a hint from the upper level layer)
       is now passed unchanged from *_output(), so it becomes the route
       to the final destination and not to the gateway.
     + the routines will return 0 if resolution is possible, non-zero
       otherwise.
     + arpresolve() returns EWOULDBLOCK in case the mbuf is being held
       waiting for an arp reply -- in this case the error code is masked
       in the caller so the upper layer protocol will not see a failure.

2. arpcom untangling
    Where possible, use 'struct ifnet' instead of 'struct arpcom' variables,
    and use the IFP2AC macro to access arpcom fields.
    This mostly affects the netatalk code.

=== Detailed changes: ===
net/if_arcsubr.c
   rt_check() cleanup, remove a useless variable

net/if_atmsubr.c
   rt_check() cleanup

net/if_ethersubr.c
   rt_check() cleanup, arpcom untangling

net/if_fddisubr.c
   rt_check() cleanup, arpcom untangling

net/if_iso88025subr.c
   rt_check() cleanup

netatalk/aarp.c
   arpcom untangling, remove a block of duplicated code

netatalk/at_extern.h
   arpcom untangling

netinet/if_ether.c
   rt_check() cleanup (change arpresolve)

netinet6/nd6.c
   rt_check() cleanup (change nd6_storelladdr)
2004-04-25 09:24:52 +00:00
Luigi Rizzo
49572c5b0d arpcom untangling:
- use ifp instead if &ac->ac_if in a couple of nd6* calls;
   this removes a useless dependency.

 - use IFP2AC(ifp) instead of an extra variable to point to the struct arpcom;
   this does not remove the nesting dependency between arpcom and ifnet but
   makes it more evident.
2004-04-24 21:59:41 +00:00
Luigi Rizzo
4158372f1a replace Bcmp() with the same bcmp() used in the rest of the file. 2004-04-18 11:01:15 +00:00