Index: sys/net/bpf.c =================================================================== --- sys/net/bpf.c (revision 228435) +++ sys/net/bpf.c (working copy) @@ -1,12 +1,17 @@ /*- * Copyright (c) 1990, 1991, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. + * Copyright (c) 2011 The University of Melbourne. + * All rights reserved. * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * + * Portions of this software were developed by Julien Ridoux at the University + * of Melbourne under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -39,6 +44,7 @@ #include "opt_bpf.h" #include "opt_compat.h" +#include "opt_ffclock.h" #include "opt_netgraph.h" #include @@ -55,6 +61,9 @@ #include #include #include +#ifdef FFCLOCK +#include +#endif #include #include @@ -106,13 +115,20 @@ * 32-bit the first time we see a 32-bit compat ioctl request. */ struct bpf_hdr32 { +#ifdef FFCLOCK + union { + struct timeval32 time_stamp; /* time stamp */ + ffcounter ffcount_stamp; /* f-forward counter */ + } bh_stamp; +#else struct timeval32 bh_tstamp; /* time stamp */ +#endif uint32_t bh_caplen; /* length of captured portion */ uint32_t bh_datalen; /* original length of packet */ uint16_t bh_hdrlen; /* length of bpf header (this struct plus alignment padding) */ }; -#endif +#endif /* !BURN_BRIDGES */ struct bpf_program32 { u_int bf_len; @@ -130,7 +146,21 @@ #define BIOCGDLTLIST32 _IOWR('B', 121, struct bpf_dltlist32) #define BIOCSETWF32 _IOW('B', 123, struct bpf_program32) #define BIOCSETFNR32 _IOW('B', 130, struct bpf_program32) +#endif /* COMPAT_FREEBSD32 */ + +#ifdef FFCLOCK +/* + * Safety belt to ensure ABI of structs bpf_hdr32, bpf_hdr and bpf_xhdr are + * preserved when FFCLOCK is enabled, which changes the stamp field in the + * structs to allow storing a regular time stamp or ffcounter stamp. + */ +CTASSERT(sizeof(struct timeval) >= sizeof(ffcounter) && +#if defined(COMPAT_FREEBSD32) && !defined(BURN_BRIDGES) + sizeof(struct timeval32) >= sizeof(ffcounter) && #endif + sizeof(struct bpf_ts) >= sizeof(ffcounter) && + sizeof(struct bintime) >= sizeof(ffcounter)); +#endif /* * bpf_iflist is a list of BPF interface structures, each corresponding to a @@ -148,12 +178,19 @@ static int bpf_movein(struct uio *, int, struct ifnet *, struct mbuf **, struct sockaddr *, int *, struct bpf_insn *); static int bpf_setif(struct bpf_d *, struct ifreq *); +#ifdef FFCLOCK +static void bpf_set_sysclock_flags(struct bpf_d *, unsigned int); +#endif static void bpf_timed_out(void *); static __inline void bpf_wakeup(struct bpf_d *); static void catchpacket(struct bpf_d *, u_char *, u_int, u_int, void (*)(struct bpf_d *, caddr_t, u_int, void *, u_int), +#ifdef FFCLOCK + struct sysclock_snap *); +#else struct bintime *); +#endif static void reset_d(struct bpf_d *); static int bpf_setf(struct bpf_d *, struct bpf_program *, u_long cmd); static int bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *); @@ -172,6 +209,8 @@ &bpf_zerocopy_enable, 0, "Enable new zero-copy BPF buffer sessions"); static SYSCTL_NODE(_net_bpf, OID_AUTO, stats, CTLFLAG_MPSAFE | CTLFLAG_RW, bpf_stats_sysctl, "bpf statistics portal"); +static SYSCTL_NODE(_net_bpf, OID_AUTO, tscfg, CTLFLAG_RW, NULL, + "Per-interface timestamp configuration"); static d_open_t bpfopen; static d_read_t bpfread; @@ -662,7 +701,31 @@ free(d, M_BPF); } +#ifdef FFCLOCK /* + * Set the system clock flags on a descriptor. This specifies how the clock + * selected will compose the timestamp associated with each packet. + */ +static void +bpf_set_sysclock_flags(struct bpf_d *d, unsigned int flags) +{ + + d->bd_sysclock_flags = FFCLOCK_LERP; + + if (flags & BPF_T_MONOTONIC) { + d->bd_sysclock_flags |= FBCLOCK_UPTIME; + d->bd_sysclock_flags |= FFCLOCK_UPTIME; + } else + d->bd_sysclock_flags |= FFCLOCK_LEAPSEC; + + if ((flags & BPF_T_FAST) == BPF_T_FAST) { + d->bd_sysclock_flags |= FBCLOCK_FAST; + d->bd_sysclock_flags |= FFCLOCK_FAST; + } +} +#endif + +/* * Open ethernet device. Returns ENXIO for illegal minor device number, * EBUSY if file is open by another process. */ @@ -690,6 +753,9 @@ d->bd_sig = SIGIO; d->bd_direction = BPF_D_INOUT; d->bd_pid = td->td_proc->p_pid; +#ifdef FFCLOCK + bpf_set_sysclock_flags(d, 0); +#endif #ifdef MAC mac_bpfdesc_init(d); mac_bpfdesc_create(td->td_ucred, d); @@ -1406,8 +1472,18 @@ u_int func; func = *(u_int *)addr; - if (BPF_T_VALID(func)) +#ifndef FFCLOCK + if (BPF_T_FORMAT(func) == BPF_T_FFCOUNTER || + BPF_T_CLOCK(func) != BPF_T_SYSCLOCK) { + error = EINVAL; + } else +#endif + if (BPF_T_VALID(func)) { d->bd_tstamp = func; +#ifdef FFCLOCK + bpf_set_sysclock_flags(d, func); +#endif + } else error = EINVAL; } @@ -1777,7 +1853,12 @@ } static int +#ifdef FFCLOCK +bpf_gettime(struct sysclock_snap *cs, int tstype, int sysclock_flags, + struct mbuf *m) +#else bpf_gettime(struct bintime *bt, int tstype, struct mbuf *m) +#endif { struct m_tag *tag; int quality; @@ -1789,15 +1870,35 @@ if (m != NULL) { tag = m_tag_locate(m, MTAG_BPF, MTAG_BPF_TIMESTAMP, NULL); if (tag != NULL) { +#ifdef FFCLOCK + /* FIXME this is really ugly, but should not break + * any code using the cs + */ + struct bintime *bt; + bt = (struct bintime *)(tag + 1); + bzero(cs, sizeof(struct sysclock_snap)); + cs->fb_info.tick_time = *bt; +#else *bt = *(struct bintime *)(tag + 1); + if ((tstype & BPF_T_MONOTONIC) == 0) + bintime_add(bt, &boottimebin); +#endif return (BPF_TSTAMP_EXTERN); } } + +#ifdef FFCLOCK + sysclock_getsnapshot(cs, sysclock_flags); +#else if (quality == BPF_TSTAMP_NORMAL) binuptime(bt); else getbinuptime(bt); + if ((tstype & BPF_T_MONOTONIC) == 0) + bintime_add(bt, &boottimebin); +#endif + return (quality); } @@ -1810,7 +1911,11 @@ void bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktlen) { +#ifdef FFCLOCK + struct sysclock_snap cs; +#else struct bintime bt; +#endif struct bpf_d *d; #ifdef BPF_JITTER bpf_jit_filter *bf; @@ -1839,12 +1944,23 @@ if (slen != 0) { d->bd_fcount++; if (gottime < bpf_ts_quality(d->bd_tstamp)) +#ifdef FFCLOCK + /* FIXME the flags should not be be flags from the value of the + * sysctl leaving in bpf_if *bp */ + gottime = bpf_gettime(&cs, d->bd_tstamp, + d->bd_sysclock_flags, NULL); +#else gottime = bpf_gettime(&bt, d->bd_tstamp, NULL); +#endif #ifdef MAC if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0) #endif catchpacket(d, pkt, pktlen, slen, +#ifdef FFCLOCK + bpf_append_bytes, &cs); +#else bpf_append_bytes, &bt); +#endif } BPFD_UNLOCK(d); } @@ -1861,7 +1977,11 @@ void bpf_mtap(struct bpf_if *bp, struct mbuf *m) { +#ifdef FFCLOCK + struct sysclock_snap cs; +#else struct bintime bt; +#endif struct bpf_d *d; #ifdef BPF_JITTER bpf_jit_filter *bf; @@ -1895,12 +2015,23 @@ if (slen != 0) { d->bd_fcount++; if (gottime < bpf_ts_quality(d->bd_tstamp)) +#ifdef FFCLOCK + /* FIXME the flags should not be be flags from the value of the + * sysctl leaving in bpf_if *bp */ + gottime = bpf_gettime(&cs, d->bd_tstamp, + d->bd_sysclock_flags, m); +#else gottime = bpf_gettime(&bt, d->bd_tstamp, m); +#endif #ifdef MAC if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0) #endif catchpacket(d, (u_char *)m, pktlen, slen, +#ifdef FFCLOCK + bpf_append_mbuf, &cs); +#else bpf_append_mbuf, &bt); +#endif } BPFD_UNLOCK(d); } @@ -1914,7 +2045,11 @@ void bpf_mtap2(struct bpf_if *bp, void *data, u_int dlen, struct mbuf *m) { +#ifdef FFCLOCK + struct sysclock_snap cs; +#else struct bintime bt; +#endif struct mbuf mb; struct bpf_d *d; u_int pktlen, slen; @@ -1948,12 +2083,23 @@ if (slen != 0) { d->bd_fcount++; if (gottime < bpf_ts_quality(d->bd_tstamp)) +#ifdef FFCLOCK + /* FIXME the flags should not be be flags from the value of the + * sysctl leaving in bpf_if *bp */ + gottime = bpf_gettime(&cs, d->bd_tstamp, + d->bd_sysclock_flags, m); +#else gottime = bpf_gettime(&bt, d->bd_tstamp, m); +#endif #ifdef MAC if (mac_bpfdesc_check_receive(d, bp->bif_ifp) == 0) #endif catchpacket(d, (u_char *)&mb, pktlen, slen, +#ifdef FFCLOCK + bpf_append_mbuf, &cs); +#else bpf_append_mbuf, &bt); +#endif } BPFD_UNLOCK(d); } @@ -1998,15 +2144,9 @@ static void bpf_bintime2ts(struct bintime *bt, struct bpf_ts *ts, int tstype) { - struct bintime bt2; struct timeval tsm; struct timespec tsn; - if ((tstype & BPF_T_MONOTONIC) == 0) { - bt2 = *bt; - bintime_add(&bt2, &boottimebin); - bt = &bt2; - } switch (BPF_T_FORMAT(tstype)) { case BPF_T_MICROTIME: bintime2timeval(bt, &tsm); @@ -2035,7 +2175,11 @@ static void catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen, void (*cpfn)(struct bpf_d *, caddr_t, u_int, void *, u_int), +#ifdef FFCLOCK + struct sysclock_snap *cs) +#else struct bintime *bt) +#endif { struct bpf_xhdr hdr; #ifndef BURN_BRIDGES @@ -2044,6 +2188,9 @@ struct bpf_hdr32 hdr32_old; #endif #endif +#ifdef FFCLOCK + struct bintime bt; +#endif int caplen, curlen, hdrlen, totlen; int do_wakeup = 0; int do_timestamp; @@ -2118,7 +2265,19 @@ if (tstype == BPF_T_NONE || BPF_T_FORMAT(tstype) == BPF_T_MICROTIME) { struct bpf_ts ts; if (do_timestamp) +#ifdef FFCLOCK + /* FIXME we don't want to call sysclock_snap2binitme if + * the source of the timestamp is BPF_TSTAMP_EXTERN. + * Do simple copy into bt instead + * In the current state of things, it would require to pass the + * quality returned by bpf_gettime to catchpacket. + * To check with Lawrence patch. + */ + sysclock_snap2bintime(cs, &bt, d->bd_sysclock_flags); + bpf_bintime2ts(&bt, &ts, tstype); +#else bpf_bintime2ts(bt, &ts, tstype); +#endif #ifdef COMPAT_FREEBSD32 if (d->bd_compat32) { bzero(&hdr32_old, sizeof(hdr32_old)); @@ -2153,8 +2312,23 @@ * move forward the length of the header plus padding. */ bzero(&hdr, sizeof(hdr)); - if (do_timestamp) + if (do_timestamp) { +#ifdef FFCLOCK + if ((BPF_T_FORMAT(tstype) == BPF_T_FFCOUNTER)) + bcopy(&(cs->ffcount), &hdr.bh_tstamp, sizeof(ffcounter)); + else { + /* FIXME we don't want to call sysclock_snap2binitme if + * the source of the timestamp is BPF_TSTAMP_EXTERN. + * Do simple copy into bt instead + * Need Lawrence patch + */ + sysclock_snap2bintime(cs, &bt, d->bd_sysclock_flags); + bpf_bintime2ts(&bt, &hdr.bh_tstamp, tstype); + } +#else bpf_bintime2ts(bt, &hdr.bh_tstamp, tstype); +#endif + } hdr.bh_datalen = pktlen; hdr.bh_hdrlen = hdrlen; hdr.bh_caplen = caplen; @@ -2199,6 +2373,49 @@ mtx_destroy(&d->bd_mtx); } +static const char *bpftstypes[] = { + "none", +#define BPF_TSTYPE_NONE 0 + "fast", +#define BPF_TSTYPE_FAST 1 + "normal", +#define BPF_TSTYPE_NORMAL 2 + "external" +#define BPF_TSTYPE_EXTERNAL 3 +}; +#define NUM_BPFTSTYPES (sizeof(bpftstypes) / sizeof(*bpftstypes)) + +static int +bpf_tscfg_sysctl_handler(SYSCTL_HANDLER_ARGS) +{ + char tstype_name[16]; + struct bpf_if *bp; + int error, tstype; + + bp = (struct bpf_if *)arg1; + + if (req->newptr == NULL) { + /* Return the name of the BPF interface's timestamp setting. */ + strlcpy(tstype_name, bpftstypes[bp->tstype], + sizeof(tstype_name)); + error = sysctl_handle_string(oidp, tstype_name, + sizeof(tstype_name), req); + } else { + /* Change the timestamp configuration for this BPF interface. */ + error = EINVAL; + for (tstype = 0; tstype < NUM_BPFTSTYPES; tstype++) { + if (strncmp((char *)req->newptr, bpftstypes[tstype], + strlen(bpftstypes[tstype])) == 0) { + bp->tstype = tstype; + error = 0; + break; + } + } + } + + return (error); +} + /* * Attach an interface to bpf. dlt is the link layer type; hdrlen is the * fixed size of the link header (variable length headers not yet supported). @@ -2225,6 +2442,16 @@ if (bp == NULL) panic("bpfattach"); + bp->tscfgoid = SYSCTL_ADD_PROC(NULL, + SYSCTL_STATIC_CHILDREN(_net_bpf_tscfg), OID_AUTO, ifp->if_xname, + CTLFLAG_RW, bp, sizeof(bp), bpf_tscfg_sysctl_handler, "A", + "Interface BPF timestamp configuration"); + if (bp->tscfgoid == NULL) { + free(bp, M_BPF); + panic("bpfattach tscfgoid"); + } + + bp->tstype = BPF_TSTYPE_NORMAL; LIST_INIT(&bp->bif_dlist); bp->bif_ifp = ifp; bp->bif_dlt = dlt; @@ -2278,6 +2505,7 @@ BPFD_UNLOCK(d); } + sysctl_remove_oid(bp->tscfgoid, 1, 0); mtx_destroy(&bp->bif_mtx); free(bp, M_BPF); } Index: sys/net/bpf.h =================================================================== --- sys/net/bpf.h (revision 228435) +++ sys/net/bpf.h (working copy) @@ -1,12 +1,17 @@ /*- * Copyright (c) 1990, 1991, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. + * Copyright (c) 2011 The University of Melbourne. + * All rights reserved. * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * + * Portions of this software were developed by Julien Ridoux at the University + * of Melbourne under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -164,17 +169,26 @@ #define BPF_T_NANOTIME 0x0001 #define BPF_T_BINTIME 0x0002 #define BPF_T_NONE 0x0003 -#define BPF_T_FORMAT_MASK 0x0003 +#define BPF_T_FFCOUNTER 0x0004 +#define BPF_T_FORMAT_MAX 0x0004 +#define BPF_T_FORMAT_MASK 0x0007 #define BPF_T_NORMAL 0x0000 #define BPF_T_FAST 0x0100 #define BPF_T_MONOTONIC 0x0200 #define BPF_T_MONOTONIC_FAST (BPF_T_FAST | BPF_T_MONOTONIC) #define BPF_T_FLAG_MASK 0x0300 +#define BPF_T_SYSCLOCK 0x0000 +#define BPF_T_FBCLOCK 0x1000 +#define BPF_T_FFCLOCK 0x2000 +#define BPF_T_CLOCK_MAX 0x2000 +#define BPF_T_CLOCK_MASK 0x3000 #define BPF_T_FORMAT(t) ((t) & BPF_T_FORMAT_MASK) #define BPF_T_FLAG(t) ((t) & BPF_T_FLAG_MASK) -#define BPF_T_VALID(t) \ - ((t) == BPF_T_NONE || (BPF_T_FORMAT(t) != BPF_T_NONE && \ - ((t) & ~(BPF_T_FORMAT_MASK | BPF_T_FLAG_MASK)) == 0)) +#define BPF_T_CLOCK(t) ((t) & BPF_T_CLOCK_MASK) +#define BPF_T_VALID(t) \ + ((t) == BPF_T_NONE || (t) == BPF_T_FFCOUNTER || \ + (BPF_T_FORMAT(t) <= BPF_T_BINTIME && BPF_T_CLOCK(t) <= BPF_T_CLOCK_MAX && \ + ((t) & ~(BPF_T_FORMAT_MASK | BPF_T_FLAG_MASK | BPF_T_CLOCK_MASK)) == 0)) #define BPF_T_MICROTIME_FAST (BPF_T_MICROTIME | BPF_T_FAST) #define BPF_T_NANOTIME_FAST (BPF_T_NANOTIME | BPF_T_FAST) @@ -186,6 +200,44 @@ #define BPF_T_NANOTIME_MONOTONIC_FAST (BPF_T_NANOTIME | BPF_T_MONOTONIC_FAST) #define BPF_T_BINTIME_MONOTONIC_FAST (BPF_T_BINTIME | BPF_T_MONOTONIC_FAST) +#define BPF_T_FBCLOCK_MICROTIME_FAST \ + (BPF_T_MICROTIME_FAST | BPF_T_FBCLOCK) +#define BPF_T_FBCLOCK_NANOTIME_FAST \ + (BPF_T_NANOTIME_FAST | BPF_T_FBCLOCK) +#define BPF_T_FBCLOCK_BINTIME_FAST \ + (BPF_T_BINTIME_FAST | BPF_T_FBCLOCK) +#define BPF_T_FBCLOCK_MICROTIME_MONOTONIC \ + (BPF_T_MICROTIME_MONOTONIC | BPF_T_FBCLOCK) +#define BPF_T_FBCLOCK_NANOTIME_MONOTONIC \ + (BPF_T_NANOTIME_MONOTONIC | BPF_T_FBCLOCK) +#define BPF_T_FBCLOCK_BINTIME_MONOTONIC \ + (BPF_T_BINTIME_MONOTONIC | BPF_T_FBCLOCK) +#define BPF_T_FBCLOCK_MICROTIME_MONOTONIC_FAST \ + (BPF_T_MICROTIME_MONOTONIC_FAST | BPF_T_FBCLOCK) +#define BPF_T_FBCLOCK_NANOTIME_MONOTONIC_FAST \ + (BPF_T_NANOTIME_MONOTONIC_FAST | BPF_T_FBCLOCK) +#define BPF_T_FBCLOCK_BINTIME_MONOTONIC_FAST \ + (BPF_T_BINTIME_MONOTONIC_FAST | BPF_T_FBCLOCK) + +#define BPF_T_FFCLOCK_MICROTIME_FAST \ + (BPF_T_MICROTIME_FAST | BPF_T_FFCLOCK) +#define BPF_T_FFCLOCK_NANOTIME_FAST \ + (BPF_T_NANOTIME_FAST | BPF_T_FFCLOCK) +#define BPF_T_FFCLOCK_BINTIME_FAST \ + (BPF_T_BINTIME_FAST | BPF_T_FFCLOCK) +#define BPF_T_FFCLOCK_MICROTIME_MONOTONIC \ + (BPF_T_MICROTIME_MONOTONIC | BPF_T_FFCLOCK) +#define BPF_T_FFCLOCK_NANOTIME_MONOTONIC \ + (BPF_T_NANOTIME_MONOTONIC | BPF_T_FFCLOCK) +#define BPF_T_FFCLOCK_BINTIME_MONOTONIC \ + (BPF_T_BINTIME_MONOTONIC | BPF_T_FFCLOCK) +#define BPF_T_FFCLOCK_MICROTIME_MONOTONIC_FAST \ + (BPF_T_MICROTIME_MONOTONIC_FAST | BPF_T_FFCLOCK) +#define BPF_T_FFCLOCK_NANOTIME_MONOTONIC_FAST \ + (BPF_T_NANOTIME_MONOTONIC_FAST | BPF_T_FFCLOCK) +#define BPF_T_FFCLOCK_BINTIME_MONOTONIC_FAST \ + (BPF_T_BINTIME_MONOTONIC_FAST | BPF_T_FFCLOCK) + /* * Structure prepended to each packet. */ @@ -193,8 +245,20 @@ bpf_int64 bt_sec; /* seconds */ bpf_u_int64 bt_frac; /* fraction */ }; + +#ifdef FFCLOCK +#define bh_tstamp bh_stamp.time_stamp +#endif + struct bpf_xhdr { +#ifdef FFCLOCK + union { + struct bpf_ts time_stamp; /* time stamp */ + ffcounter ffcount_stamp; /* feed-forward counter */ + } bh_stamp; +#else struct bpf_ts bh_tstamp; /* time stamp */ +#endif bpf_u_int32 bh_caplen; /* length of captured portion */ bpf_u_int32 bh_datalen; /* original length of packet */ u_short bh_hdrlen; /* length of bpf header (this struct @@ -202,7 +266,14 @@ }; /* Obsolete */ struct bpf_hdr { +#ifdef FFCLOCK + union { + struct timeval time_stamp; /* time stamp */ + ffcounter ffcount_stamp; /* feed-forward counter */ + } bh_stamp; +#else struct timeval bh_tstamp; /* time stamp */ +#endif bpf_u_int32 bh_caplen; /* length of captured portion */ bpf_u_int32 bh_datalen; /* original length of packet */ u_short bh_hdrlen; /* length of bpf header (this struct @@ -1100,6 +1171,8 @@ u_int bif_hdrlen; /* length of link header */ struct ifnet *bif_ifp; /* corresponding interface */ struct mtx bif_mtx; /* mutex for interface */ + struct sysctl_oid *tscfgoid; /* timestamp sysctl oid for interface */ + int tstype; /* timestamp setting for interface */ }; void bpf_bufheld(struct bpf_d *d); Index: sys/net/bpfdesc.h =================================================================== --- sys/net/bpfdesc.h (revision 228435) +++ sys/net/bpfdesc.h (working copy) @@ -82,6 +82,7 @@ int bd_hdrcmplt; /* false to fill in src lladdr automatically */ int bd_direction; /* select packet direction */ int bd_tstamp; /* select time stamping function */ + int bd_sysclock_flags; /* holds system clock flags */ int bd_feedback; /* true to feed back sent packets */ int bd_async; /* non-zero if packet reception should generate signal */ int bd_sig; /* signal to send upon packet reception */