[RFC] add macros for ifnet statistic accounting
Andrey V. Elsukov
ae at FreeBSD.org
Fri Dec 19 14:50:52 UTC 2014
On 20.11.2014 20:38, Adrian Chadd wrote:
> On 20 November 2014 09:33, Andrey V. Elsukov <ae at freebsd.org> wrote:
>> Hi All,
>>
>> we already did some changes in network stack in head/, that made ability
>> for merging changes into stable branches much harder.
>>
>> What you think about adding the following macro to head/:
>>
>> --- if_var.h (revision 274736)
>> +++ if_var.h (working copy)
>> @@ -111,6 +111,10 @@ typedef enum {
>> IFCOUNTERS /* Array size. */
>> } ift_counter;
>>
>> +#define IFSTAT_ADD(ifp, name, value) \
>> + if_inc_counter((ifp), IFCOUNTER_ ## name, (value))
>> +#define IFSTAT_INC(ifp, name) IFSTAT_ADD(ifp, name, 1)
>> +
>> typedef struct ifnet * if_t;
>>
>> typedef void (*if_start_fn_t)(if_t);
>>
>>
>> And then make a direct commit to stable/* branches like this:
>>
>> --- if_var.h (revision 274750)
>> +++ if_var.h (working copy)
>> @@ -104,6 +104,23 @@ VNET_DECLARE(struct pfil_head, link_pfil_hook); /*
>> #define V_link_pfil_hook VNET(link_pfil_hook)
>> #endif /* _KERNEL */
>>
>> +#define IFSTAT_ADD(ifp, name, value) \
>> + IFSTAT_ ## name ## _ADD(ifp, value)
>> +#define IFSTAT_INC(ifp, name) IFSTAT_ADD(ifp, name, 1)
>> +
>> +#define IFSTAT_IPACKETS_ADD(ifp, inc) (ifp)->if_ipackets += (inc)
>> +#define IFSTAT_IERRORS_ADD(ifp, inc) (ifp)->if_ierrors += (inc)
>> +#define IFSTAT_OPACKETS_ADD(ifp, inc) (ifp)->if_opackets += (inc)
>> +#define IFSTAT_OERRORS_ADD(ifp, inc) (ifp)->if_oerrors += (inc)
>> +#define IFSTAT_COLLISIONS_ADD(ifp, inc) (ifp)->if_collisions += (inc)
>> +#define IFSTAT_IBYTES_ADD(ifp, inc) (ifp)->if_ibytes += (inc)
>> +#define IFSTAT_OBYTES_ADD(ifp, inc) (ifp)->if_obytes += (inc)
>> +#define IFSTAT_IMCASTS_ADD(ifp, inc) (ifp)->if_imcasts += (inc)
>> +#define IFSTAT_OMCASTS_ADD(ifp, inc) (ifp)->if_omcasts += (inc)
>> +#define IFSTAT_IQDROPS_ADD(ifp, inc) (ifp)->if_iqdrops += (inc)
>> +#define IFSTAT_OQDROPS_ADD(ifp, inc) /* NOP */
>> +#define IFSTAT_NOPROTO_ADD(ifp, inc) (ifp)->if_noproto += (inc)
>> +
>> /*
>> * Structure defining a queue for a network interface.
>> */
>>
>> This can make merging a little bit easier, at least for generic code in
>> the network stack.
It looks there are not so much people, who wants this feature. We
discussed this with glebius@ and probably the better solution will be
merging ift_counter enum and adding if_inc_counter() function to
stable/10. I looked how other BSDs doing this accounting and only DfBSD
has macro IFNET_STAT_INC(). But since we are planning to make opaque
ifnet, it doesn't matter how we will do accounting, anyway it will be
incompatible with other BSDs.
If there is no objections I'll commit this after weekend.
Index: if.c
===================================================================
--- if.c (revision 275939)
+++ if.c (working copy)
@@ -1450,6 +1450,56 @@ if_rtdel(struct radix_node *rn, void *arg)
}
/*
+ * A compatibility function returns ifnet counter values.
+ */
+uint64_t
+if_get_counter_default(struct ifnet *ifp, ift_counter cnt)
+{
+
+ KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
+
+ switch (cnt) {
+ case IFCOUNTER_IPACKETS: return (ifp->if_ipackets);
+ case IFCOUNTER_IERRORS: return (ifp->if_ierrors);
+ case IFCOUNTER_OPACKETS: return (ifp->if_opackets);
+ case IFCOUNTER_OERRORS: return (ifp->if_oerrors);
+ case IFCOUNTER_COLLISIONS: return (ifp->if_collisions);
+ case IFCOUNTER_IBYTES: return (ifp->if_ibytes);
+ case IFCOUNTER_OBYTES: return (ifp->if_obytes);
+ case IFCOUNTER_IMCASTS: return (ifp->if_imcasts);
+ case IFCOUNTER_OMCASTS: return (ifp->if_omcasts);
+ case IFCOUNTER_IQDROPS: return (ifp->if_iqdrops);
+ case IFCOUNTER_NOPROTO: return (ifp->if_noproto);
+ };
+ return (0);
+}
+
+/*
+ * Increase an ifnet counter. Usually used for counters shared
+ * between the stack and a driver, but function supports them all.
+ */
+void
+if_inc_counter(struct ifnet *ifp, ift_counter cnt, int64_t inc)
+{
+
+ KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
+
+ switch (cnt) {
+ case IFCOUNTER_IPACKETS: ifp->if_ipackets += inc; break;
+ case IFCOUNTER_IERRORS: ifp->if_ierrors += inc; break;
+ case IFCOUNTER_OPACKETS: ifp->if_opackets += inc; break;
+ case IFCOUNTER_OERRORS: ifp->if_oerrors += inc; break;
+ case IFCOUNTER_COLLISIONS: ifp->if_collisions += inc; break;
+ case IFCOUNTER_IBYTES: ifp->if_ibytes += inc; break;
+ case IFCOUNTER_OBYTES: ifp->if_obytes += inc; break;
+ case IFCOUNTER_IMCASTS: ifp->if_imcasts += inc; break;
+ case IFCOUNTER_OMCASTS: ifp->if_omcasts += inc; break;
+ case IFCOUNTER_IQDROPS: ifp->if_iqdrops += inc; break;
+ case IFCOUNTER_NOPROTO: ifp->if_noproto += inc; break;
+ };
+}
+
+/*
* Wrapper functions for struct ifnet address list locking macros.
These are
* used by kernel modules to avoid encoding programming interface or binary
* interface assumptions that may be violated when kernel-internal locking
Index: if_var.h
===================================================================
--- if_var.h (revision 275939)
+++ if_var.h (working copy)
@@ -104,6 +104,22 @@ VNET_DECLARE(struct pfil_head, link_pfil_hook); /*
#define V_link_pfil_hook VNET(link_pfil_hook)
#endif /* _KERNEL */
+typedef enum {
+ IFCOUNTER_IPACKETS = 0,
+ IFCOUNTER_IERRORS,
+ IFCOUNTER_OPACKETS,
+ IFCOUNTER_OERRORS,
+ IFCOUNTER_COLLISIONS,
+ IFCOUNTER_IBYTES,
+ IFCOUNTER_OBYTES,
+ IFCOUNTER_IMCASTS,
+ IFCOUNTER_OMCASTS,
+ IFCOUNTER_IQDROPS,
+ IFCOUNTER_OQDROPS,
+ IFCOUNTER_NOPROTO,
+ IFCOUNTERS /* Array size. */
+} ift_counter;
+
/*
* Structure defining a queue for a network interface.
*/
@@ -981,6 +997,8 @@ typedef void *if_com_alloc_t(u_char type, struct i
typedef void if_com_free_t(void *com, u_char type);
void if_register_com_alloc(u_char type, if_com_alloc_t *a,
if_com_free_t *f);
void if_deregister_com_alloc(u_char type);
+uint64_t if_get_counter_default(struct ifnet *, ift_counter);
+void if_inc_counter(struct ifnet *, ift_counter, int64_t);
#define IF_LLADDR(ifp) \
LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr))
--
WBR, Andrey V. Elsukov
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 538 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freebsd.org/pipermail/freebsd-net/attachments/20141219/fcc10505/attachment.sig>
More information about the freebsd-net
mailing list