<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/tap.c, branch 2026_07_16.090d739</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>dhcpv6: Fix reply destination to match client's source address</title>
<updated>2026-07-14T23:21:20+00:00</updated>
<author>
<name>Jon Maloy</name>
<email>jmaloy@redhat.com</email>
</author>
<published>2026-07-10T21:58:33+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=fce94309868c902a4242f903ba4f406e32d2d9b6'/>
<id>fce94309868c902a4242f903ba4f406e32d2d9b6</id>
<content type='text'>
tap_ip6_daddr() selects the reply destination based on our source
address type (link-local), so it always returns addr_ll_seen. But if
the client sent from a global address, we would reply to an address
different from what the client is expecting. Since RFC 9915 (section
18.3.10) allows clients to use global addresses for DHCPv6, we now
correct this, and always respond to the address the client was using.

We also remove a redundant addr_ll_seen assignment, since this is
already done by tap.c when processing IPv6 packets.

Note: if the client uses a global source address, our reply will
still have a link-local source, creating a scope mismatch. Fixing
this properly would require a mechanism to allocate a global address
for the DHCPv6 server, which we currently don't have. Responding to
the client's actual source address is still a net improvement over the
previous behavior of replying to an unrelated cached address.

Note 2: This commit isn't actually a fix to an observed problem, but
rather an answer to a theoretical issue, adding completeness to the
mechanism and simplifying subsequent changes in this series.

Signed-off-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
tap_ip6_daddr() selects the reply destination based on our source
address type (link-local), so it always returns addr_ll_seen. But if
the client sent from a global address, we would reply to an address
different from what the client is expecting. Since RFC 9915 (section
18.3.10) allows clients to use global addresses for DHCPv6, we now
correct this, and always respond to the address the client was using.

We also remove a redundant addr_ll_seen assignment, since this is
already done by tap.c when processing IPv6 packets.

Note: if the client uses a global source address, our reply will
still have a link-local source, creating a scope mismatch. Fixing
this properly would require a mechanism to allocate a global address
for the DHCPv6 server, which we currently don't have. Responding to
the client's actual source address is still a net improvement over the
previous behavior of replying to an unrelated cached address.

Note 2: This commit isn't actually a fix to an observed problem, but
rather an answer to a theoretical issue, adding completeness to the
mechanism and simplifying subsequent changes in this series.

Signed-off-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tap: don't let overheard traffic move addr_seen when address is explicit</title>
<updated>2026-06-19T11:10:24+00:00</updated>
<author>
<name>EJ Campbell</name>
<email>ej.campbell@gmail.com</email>
</author>
<published>2026-06-11T04:26:19+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=3f57f0382f6a72c0b8ce0c5ff92248b5117ed9b6'/>
<id>3f57f0382f6a72c0b8ce0c5ff92248b5117ed9b6</id>
<content type='text'>
When pasta's tap interface shares an L2 segment with other endpoints
(e.g. bridged in a namespace with a VM behind a second tap), frames
from those endpoints flood to pasta and their source addresses
overwrite addr_seen — inbound flows are then spliced or forwarded to
whichever address spoke last instead of the configured guest.

In such a setup the namespace kernel's own broadcasts (ARP probes,
IGMP joins, sourced from the bridge address) race the guest's traffic
for addr_seen, and inbound port-forwarded connections intermittently
get RST after pasta dials the bridge address, where nothing listens:

  Flow 0 (TCP connection (spliced)):
    HOST [127.0.0.1]:57280 -&gt; [127.0.0.2]:22844
      =&gt; SPLICE [0.0.0.0]:0 -&gt; [10.0.2.1]:80    &lt;- bridge addr, not -a
  Flow 0 (TCP connection (spliced)): Error event on socket: Connection refused

When -a / --address is given, the user has explicitly said where the
guest is: track that decision with a new addr_fixed flag (per address
family) and skip the addr_seen updates in the tap handlers. Behaviour
without -a is unchanged, and IPv6 link-local tracking (addr_ll_seen)
is unaffected — a global -a says nothing about which link-local
address the guest chose.

With this change, a reproducer that previously failed one run in three
(99 spliced connections per run) passed six consecutive runs.

Signed-off-by: EJ Campbell &lt;ej.campbell@gmail.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When pasta's tap interface shares an L2 segment with other endpoints
(e.g. bridged in a namespace with a VM behind a second tap), frames
from those endpoints flood to pasta and their source addresses
overwrite addr_seen — inbound flows are then spliced or forwarded to
whichever address spoke last instead of the configured guest.

In such a setup the namespace kernel's own broadcasts (ARP probes,
IGMP joins, sourced from the bridge address) race the guest's traffic
for addr_seen, and inbound port-forwarded connections intermittently
get RST after pasta dials the bridge address, where nothing listens:

  Flow 0 (TCP connection (spliced)):
    HOST [127.0.0.1]:57280 -&gt; [127.0.0.2]:22844
      =&gt; SPLICE [0.0.0.0]:0 -&gt; [10.0.2.1]:80    &lt;- bridge addr, not -a
  Flow 0 (TCP connection (spliced)): Error event on socket: Connection refused

When -a / --address is given, the user has explicitly said where the
guest is: track that decision with a new addr_fixed flag (per address
family) and skip the addr_seen updates in the tap handlers. Behaviour
without -a is unchanged, and IPv6 link-local tracking (addr_ll_seen)
is unaffected — a global -a says nothing about which link-local
address the guest chose.

With this change, a reproducer that previously failed one run in three
(99 spliced connections per run) passed six consecutive runs.

Signed-off-by: EJ Campbell &lt;ej.campbell@gmail.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tap: Trim Ethernet padding from short IPv4 frames instead of dropping them</title>
<updated>2026-06-19T11:10:24+00:00</updated>
<author>
<name>David du Colombier</name>
<email>0intro@gmail.com</email>
</author>
<published>2026-06-16T16:37:05+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=f072bc07b8251e513823cbb08c69a336187ec56c'/>
<id>f072bc07b8251e513823cbb08c69a336187ec56c</id>
<content type='text'>
tap4_handler() requires the L2 payload after the IP header to match
the IP datagram length exactly. Guests whose drivers pad transmitted
frames to the 60 byte Ethernet minimum, as real hardware requires and
as drivers modelled on hardware do (Plan 9's virtio-net, for one),
send pure ACK and FIN segments as 60 byte frames: 14 byte Ethernet
header, 40 byte IPv4 datagram, 6 padding octets. Those frames fail
the exact length check and are dropped without trace.

passt then never sees such a guest's acknowledgements: it
retransmits from the lowest unacknowledged sequence with exponential
backoff while the guest, which received and acknowledged everything,
waits. Every fresh connection stalls for minutes (a 1 MiB HTTP fetch
over --map-host-loopback measured 248 s before this change, 0.27 s
after; bulk transfer over established connections, whose ACKs ride
data segments above the padding threshold, is unaffected). FIN
segments are padded too, so teardown hangs as well. Note that
tap_send_single() pads passt's own outbound frames to ETH_ZLEN, so
the receive path was already stricter than the send path.

Trim the trailing padding to the IP datagram length instead, using a
new iov_tail_trim() helper, and keep dropping frames genuinely
shorter than the datagram they claim to carry. IPv6 is unaffected:
its minimal TCP frame is 74 bytes, above the padding threshold.

Signed-off-by: David du Colombier &lt;0intro@gmail.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
tap4_handler() requires the L2 payload after the IP header to match
the IP datagram length exactly. Guests whose drivers pad transmitted
frames to the 60 byte Ethernet minimum, as real hardware requires and
as drivers modelled on hardware do (Plan 9's virtio-net, for one),
send pure ACK and FIN segments as 60 byte frames: 14 byte Ethernet
header, 40 byte IPv4 datagram, 6 padding octets. Those frames fail
the exact length check and are dropped without trace.

passt then never sees such a guest's acknowledgements: it
retransmits from the lowest unacknowledged sequence with exponential
backoff while the guest, which received and acknowledged everything,
waits. Every fresh connection stalls for minutes (a 1 MiB HTTP fetch
over --map-host-loopback measured 248 s before this change, 0.27 s
after; bulk transfer over established connections, whose ACKs ride
data segments above the padding threshold, is unaffected). FIN
segments are padded too, so teardown hangs as well. Note that
tap_send_single() pads passt's own outbound frames to ETH_ZLEN, so
the receive path was already stricter than the send path.

Trim the trailing padding to the IP datagram length instead, using a
new iov_tail_trim() helper, and keep dropping frames genuinely
shorter than the datagram they claim to carry. IPv6 is unaffected:
its minimal TCP frame is 74 bytes, above the padding threshold.

Signed-off-by: David du Colombier &lt;0intro@gmail.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>conf, repair, tap: Document reasons for blocking Unix sockets</title>
<updated>2026-05-19T23:23:47+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-05-18T03:22:43+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=b64ef531b08a2969e26a2212499734940a0c6335'/>
<id>b64ef531b08a2969e26a2212499734940a0c6335</id>
<content type='text'>
Most of our operation is asynchronous, based on non-blocking fds handled
in our epoll loop.  However, our several Unix sockets (tap client, repair
helper, control client) are all blocking fds after accept().

That is in fact correct, but for not especially obvious reasons that are
slightly different in each case.  Add explanatory comments to each of them.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Fixed minor coding style detail in comment in conf_accept()]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Most of our operation is asynchronous, based on non-blocking fds handled
in our epoll loop.  However, our several Unix sockets (tap client, repair
helper, control client) are all blocking fds after accept().

That is in fact correct, but for not especially obvious reasons that are
slightly different in each case.  Add explanatory comments to each of them.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Fixed minor coding style detail in comment in conf_accept()]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>tap: Report accept() errors</title>
<updated>2026-05-19T23:22:22+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-05-18T03:22:42+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=5ef0fc44a9a334f6b433a2c795d82b89dd9f1133'/>
<id>5ef0fc44a9a334f6b433a2c795d82b89dd9f1133</id>
<content type='text'>
Currently, if accept4() fails in tap_listen_handler(), we carry on as if
it succeeded.  Something will probably fail shortly down the line, but
that's needlessly confusing.  Report an error instead.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Currently, if accept4() fails in tap_listen_handler(), we carry on as if
it succeeded.  Something will probably fail shortly down the line, but
that's needlessly confusing.  Report an error instead.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>treewide: Add SOCK_CLOEXEC to accept() calls that are missing it</title>
<updated>2026-05-19T23:22:17+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-05-18T03:22:41+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=1d16476b7de00bd5bd77b90955520a79bbec48e6'/>
<id>1d16476b7de00bd5bd77b90955520a79bbec48e6</id>
<content type='text'>
Generally we try to set the O_CLOEXEC flag on every fd we create.  This
seems to be generally accepted security best practice these days, and we
never exec(), so certainly have no need to pass fds to exec()ed processes.

A handful of accept4() calls on Unix sockets are missing the SOCK_CLOEXEC
flag to set this though.  Add the missing flag.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Generally we try to set the O_CLOEXEC flag on every fd we create.  This
seems to be generally accepted security best practice these days, and we
never exec(), so certainly have no need to pass fds to exec()ed processes.

A handful of accept4() calls on Unix sockets are missing the SOCK_CLOEXEC
flag to set this though.  Add the missing flag.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>pcap: Pass explicit L2 length to pcap_iov()</title>
<updated>2026-05-19T23:21:42+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-13T11:52:15+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=533ef11ecb4edd98c7adad3b51c40fdcc2f0671d'/>
<id>533ef11ecb4edd98c7adad3b51c40fdcc2f0671d</id>
<content type='text'>
With vhost-user multibuffer frames, the iov can be larger than the
actual L2 frame. The previous approach of computing L2 length as
iov_size() - offset would overcount and write extra bytes into the
pcap file.

Pass the L2 frame length explicitly to pcap_frame() and pcap_iov(),
and write exactly that many bytes instead of the full iov remainder.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
With vhost-user multibuffer frames, the iov can be larger than the
actual L2 frame. The previous approach of computing L2 length as
iov_size() - offset would overcount and write extra bytes into the
pcap file.

Pass the L2 frame length explicitly to pcap_frame() and pcap_iov(),
and write exactly that many bytes instead of the full iov remainder.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>checksum: Pass explicit L4 length to checksum functions</title>
<updated>2026-05-19T23:21:38+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-13T11:52:14+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=aa78f63c3c9491a9cad9f3c805a59748bd8c1ae2'/>
<id>aa78f63c3c9491a9cad9f3c805a59748bd8c1ae2</id>
<content type='text'>
The iov_tail passed to csum_iov_tail() may contain padding or trailing
data beyond the actual L4 payload.  Rather than relying on
iov_tail_size() to determine how many bytes to checksum, pass the
length explicitly so that only the relevant payload bytes are included
in the checksum computation.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The iov_tail passed to csum_iov_tail() may contain padding or trailing
data beyond the actual L4 payload.  Rather than relying on
iov_tail_size() to determine how many bytes to checksum, pass the
length explicitly so that only the relevant payload bytes are included
in the checksum computation.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ip: Prepare ip.[ch] for sharing with pesto tool</title>
<updated>2026-05-07T06:06:30+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-05-03T21:55:55+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=c9f7ed120500c630e74d1c77d2cdd670eba68368'/>
<id>c9f7ed120500c630e74d1c77d2cdd670eba68368</id>
<content type='text'>
Most things in ip.[ch] related purely to IP addresses and headers with
no dependency on other passt/pasta internals.  A number of these will be
useful to re-use in pesto.  The exception is ipv6_l4hdr() which uses
iov_tail.

The only caller of this is in tap.c, so move the function there.  Along
with moving the constant byteswapping functions to common.h, that lets
ip.[ch] to be linked into pesto as well as passt/pasta.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[sbrivio: Dropped duplicate definition of __bswap_constant_32() while
 at it, reported by Laurent]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Most things in ip.[ch] related purely to IP addresses and headers with
no dependency on other passt/pasta internals.  A number of these will be
useful to re-use in pesto.  The exception is ipv6_l4hdr() which uses
iov_tail.

The only caller of this is in tap.c, so move the function there.  Along
with moving the constant byteswapping functions to common.h, that lets
ip.[ch] to be linked into pesto as well as passt/pasta.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[sbrivio: Dropped duplicate definition of __bswap_constant_32() while
 at it, reported by Laurent]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>pesto, log: Share log.h (but not log.c) with pesto tool</title>
<updated>2026-05-07T06:06:30+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-05-03T21:55:52+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=8ad7dd45281935e8fd471fb3d3d33875ce4192b3'/>
<id>8ad7dd45281935e8fd471fb3d3d33875ce4192b3</id>
<content type='text'>
In pesto we're going to want several levels of error/warning messages, much
like passt itself.  Particularly as we start to share mode code between
passt and pesto, we want to use a similar interface to emit those.  However
we don't want to use the same implementation - logging to a file or syslog
doesn't make sense for the command line tool.

To accomplish this loosely share log.h, but not log.c between pesto and
passt.  In fact, an #ifdef means even most of log.h isn't actually shared,
but we do provide similar warn(), die() etc. macros.

This includes the *_perror() variants, which need strerror().  However,
we want to avoid allocations for pesto as we do for passt, and strerror()
allocates in some libc versions.  Therefore, also move our workaround for
this to be shared with pesto.

Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[dwg: Based on changes part of a larger patch by Stefano]
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Dropped debug_perror_() as it's not used anyway, Laurent was
 asking about its name]
[sbrivio: Fix conflicts in the Makefile caused by the fact that I'm
 not merging a previous series reworking it]
[sbrivio: For some reason, this triggers some unrelated, but valid,
 cppcheck warnings in tap.c and conf.c: fix / suppress them]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In pesto we're going to want several levels of error/warning messages, much
like passt itself.  Particularly as we start to share mode code between
passt and pesto, we want to use a similar interface to emit those.  However
we don't want to use the same implementation - logging to a file or syslog
doesn't make sense for the command line tool.

To accomplish this loosely share log.h, but not log.c between pesto and
passt.  In fact, an #ifdef means even most of log.h isn't actually shared,
but we do provide similar warn(), die() etc. macros.

This includes the *_perror() variants, which need strerror().  However,
we want to avoid allocations for pesto as we do for passt, and strerror()
allocates in some libc versions.  Therefore, also move our workaround for
this to be shared with pesto.

Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
[dwg: Based on changes part of a larger patch by Stefano]
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Dropped debug_perror_() as it's not used anyway, Laurent was
 asking about its name]
[sbrivio: Fix conflicts in the Makefile caused by the fact that I'm
 not merging a previous series reworking it]
[sbrivio: For some reason, this triggers some unrelated, but valid,
 cppcheck warnings in tap.c and conf.c: fix / suppress them]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
</feed>
