diff --git a/bsd/sys/net/if_loop.cc b/bsd/sys/net/if_loop.cc index 5697545bbd7a31e6d5db742a0f1292e0b7c8a128..09ffe899a3c4570109c15a3dd79857f8f7d883d1 100644 --- a/bsd/sys/net/if_loop.cc +++ b/bsd/sys/net/if_loop.cc @@ -35,6 +35,7 @@ */ #include <osv/ioctl.h> +#include <osv/net_trace.hh> #include <bsd/porting/netport.h> #include <bsd/sys/sys/param.h> @@ -287,6 +288,7 @@ if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen) } ifp->if_ipackets++; ifp->if_ibytes += m->M_dat.MH.MH_pkthdr.len; + log_loopback_packet(m); netisr_queue(isr, m); /* mbuf is free'd on failure. */ return (0); } diff --git a/build.mk b/build.mk index c1d77d0965bd1699b47e6e14ff8af4457855a885..c88c6eea006c9751264f14b5ac5c1426ec876352 100644 --- a/build.mk +++ b/build.mk @@ -750,6 +750,7 @@ objects += core/chart.o objects += core/net_channel.o objects += core/demangle.o objects += core/async.o +objects += core/net_trace.o include $(src)/fs/build.mk include $(src)/libc/build.mk diff --git a/core/net_trace.cc b/core/net_trace.cc new file mode 100644 index 0000000000000000000000000000000000000000..32d4961c18cdbb75fad09773c6a978a593ba9068 --- /dev/null +++ b/core/net_trace.cc @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2014 Cloudius Systems, Ltd. + * + * This work is open source software, licensed under the terms of the + * BSD license as described in the LICENSE file in the top-level directory. + */ + +#include <osv/trace.hh> +#include <osv/net_trace.hh> +#include <vector> +#include <iterator> + +class mbuf_iterator : public std::iterator<std::input_iterator_tag, char, size_t> { +private: + struct mbuf* _m; + size_t _pos; +private: + void ensure_next() + { + while (_m != nullptr && _pos == (size_t) _m->m_hdr.mh_len) { + _m = _m->m_hdr.mh_next; + _pos = 0; + } + } +public: + mbuf_iterator(struct mbuf* m) + : _m(m) + , _pos(0) + { + ensure_next(); + } + + void operator++() + { + _pos++; + ensure_next(); + } + + mbuf_iterator operator+(size_t delta) const + { + mbuf_iterator new_iterator(*this); + new_iterator += delta; + return new_iterator; + } + + void operator+=(size_t delta) + { + while (_m != nullptr && delta > 0) { + auto step = std::min(delta, _m->m_hdr.mh_len - _pos); + _pos += step; + delta -= step; + ensure_next(); + } + } + + char& operator*() + { + return _m->m_hdr.mh_data[_pos]; + } + + char* operator->() + { + return &_m->m_hdr.mh_data[_pos]; + } + + bool operator==(const mbuf_iterator& other) const + { + return other._m == _m && other._pos == _pos; + } + + bool operator!=(const mbuf_iterator& other) const + { + return !(*this == other); + } + + friend size_t std::distance<mbuf_iterator>(mbuf_iterator, mbuf_iterator); +}; + +namespace std { + +template<> +size_t distance<mbuf_iterator>(mbuf_iterator first, mbuf_iterator second) +{ + if (first._m == second._m) { + return second._pos - first._pos; + } + + size_t distance = 0; + auto* m = first._m; + + if (m) { + distance += m->m_hdr.mh_len - first._pos; + } + + m = m->m_hdr.mh_next; + + while (m && m != second._m) { + distance += m->m_hdr.mh_len; + m = m->m_hdr.mh_next; + } + + if (m) { + distance += second._pos; + } + + return distance; +} + +} + +template<size_t limit> +class mbuf_slice : public blob_tag { +private: + struct mbuf* _m; +public: + using iterator = mbuf_iterator; + + mbuf_slice(struct mbuf* m) + : _m(m) + { + } + + iterator begin() const + { + return mbuf_iterator(_m); + } + + iterator end() const + { + return begin() + limit; + } +}; + +static constexpr size_t capture_limit = 128; +using slice_t = mbuf_slice<capture_limit>; + +TRACEPOINT(trace_net_packet_eth, "if=%d, data=%s", int, slice_t); +TRACEPOINT(trace_net_packet_loopback, "data=%s", slice_t); + +void log_eth_packet(struct ifnet *ifp, struct mbuf* m) +{ + trace_net_packet_eth(ifp->if_index, slice_t(m)); +} + +void log_loopback_packet(struct mbuf* m) +{ + trace_net_packet_loopback(slice_t(m)); +} diff --git a/drivers/virtio-net.cc b/drivers/virtio-net.cc index 3fe369300d800478b637f193b41fe6490d900c82..790a721fc36a363ecacaee761c97bcc46bad7ac5 100644 --- a/drivers/virtio-net.cc +++ b/drivers/virtio-net.cc @@ -23,8 +23,8 @@ #include <osv/debug.h> #include <osv/sched.hh> -#include "osv/trace.hh" - +#include <osv/trace.hh> +#include <osv/net_trace.hh> #include <osv/device.h> #include <osv/ioctl.h> @@ -121,6 +121,8 @@ static int if_transmit(struct ifnet* ifp, struct mbuf* m_head) { net* vnet = (net*)ifp->if_softc; + log_eth_packet(ifp, m_head); + net_d("%s_start", __FUNCTION__); /* Process packets */ @@ -447,6 +449,8 @@ void net::receiver() rx_packets++; rx_bytes += m_head->M_dat.MH.MH_pkthdr.len; + log_eth_packet(_ifn, m_head); + bool fast_path = _ifn->if_classifier.post_packet(m_head); if (!fast_path) { (*_ifn->if_input)(_ifn, m_head); diff --git a/include/osv/net_trace.hh b/include/osv/net_trace.hh new file mode 100644 index 0000000000000000000000000000000000000000..844010caa56eb995e02e9b580f43aada30c5a62e --- /dev/null +++ b/include/osv/net_trace.hh @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2014 Cloudius Systems, Ltd. + * + * This work is open source software, licensed under the terms of the + * BSD license as described in the LICENSE file in the top-level directory. + */ + +#ifndef NET_TRACE_HH +#define NET_TRACE_HH + +#include <bsd/sys/sys/mbuf.h> +#include <bsd/sys/net/if.h> + +void log_eth_packet(struct ifnet *ifp, struct mbuf *m); +void log_loopback_packet(struct mbuf *m); + +#endif