Patch from Ian Lance Taylor <ian@airs.com>:

From: Eric Norum <eric@skatter.usask.ca>
   Date: Sat,  5 Dec 98 13:20:51 -0600

   What do you think of this patch?  It implements your `tap'
   suggestion in a way that adds support for all ethernet devices with
   no driver modifications.  I also added a return value from the tap
   function.  If the return value is zero, the packet will be passed up
   the chain as usual.  If the return value is non-zero the mbuf holding
   the packet will be freed and the packet will be dropped.

   If you like it, please submit it to Joel.

   I guess there needs to be an addition to the network documentation
   describing the additional ioctl's -- and a big warning that the tap
   function is called from a context that holds the network semaphore.

   Here is Eric's patch.  I've tested it a bit, and made a couple of
   trivial changes.  This is certainly better than mine: it should work
   for all Ethernet drivers.
   ==================================================

   The only concern I have about this patch is that the tap function may
   want to fiddle with the mbuf, calling functions like m_pullup and the
   like.  If those force the networking code to rearrange the mbuf
   structure, then the caller's call to m_freem may crash.  I don't know
   if this is a realistic concern--I don't know enough about the mbuf
   layer.
This commit is contained in:
Joel Sherrill
1998-12-10 19:42:29 +00:00
parent 2ffe30d2a1
commit a3d0b8a79a
17 changed files with 131 additions and 0 deletions

View File

@@ -83,4 +83,11 @@
#define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */
#define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */
/*
* RTEMS additions for setting/getting `tap' function on incoming packets.
*/
#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */
#define SIOCGIFTAP _IOWR('i', 81, struct ifreq) /* get tap function */
#endif /* !_SYS_SOCKIO_H_ */

View File

@@ -664,6 +664,17 @@ ifioctl(so, cmd, data, p)
}
#endif
/*
* RTEMS additions for setting/getting `tap' function
*/
case SIOCSIFTAP:
ifp->if_tap = ifr->ifr_tap;
return 0;
case SIOCGIFTAP:
ifr->ifr_tap = ifp->if_tap;
return 0;
}
return (0);
}

View File

@@ -162,6 +162,8 @@ struct ifnet {
__P((struct ifnet *, struct mbuf *));
void (*if_init) /* Init routine */
__P((void *));
int (*if_tap) /* Packet filter routine */
(struct ifnet *, struct ether_header *, struct mbuf *);
struct ifqueue if_snd; /* output queue */
struct ifqueue *if_poll_slowq; /* input queue for slow devices */
};
@@ -369,6 +371,7 @@ struct ifreq {
int ifru_phys;
int ifru_media;
caddr_t ifru_data;
int (*ifru_tap)(struct ifnet *, struct ether_header *, struct mbuf *);
} ifr_ifru;
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
@@ -379,6 +382,7 @@ struct ifreq {
#define ifr_phys ifr_ifru.ifru_phys /* physical wire */
#define ifr_media ifr_ifru.ifru_media /* physical media */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
#define ifr_tap ifr_ifru.ifru_tap /* tap function */
};
struct ifaliasreq {

View File

@@ -483,6 +483,15 @@ ether_input(ifp, eh, m)
if (m->m_flags & (M_BCAST|M_MCAST))
ifp->if_imcasts++;
/*
* RTEMS addition -- allow application to `tap into'
* the incoming packet stream.
*/
if (ifp->if_tap && (*ifp->if_tap)(ifp, eh, m)) {
m_freem(m);
return;
}
ether_type = ntohs(eh->ether_type);
switch (ether_type) {

View File

@@ -83,4 +83,11 @@
#define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */
#define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */
/*
* RTEMS additions for setting/getting `tap' function on incoming packets.
*/
#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */
#define SIOCGIFTAP _IOWR('i', 81, struct ifreq) /* get tap function */
#endif /* !_SYS_SOCKIO_H_ */

View File

@@ -664,6 +664,17 @@ ifioctl(so, cmd, data, p)
}
#endif
/*
* RTEMS additions for setting/getting `tap' function
*/
case SIOCSIFTAP:
ifp->if_tap = ifr->ifr_tap;
return 0;
case SIOCGIFTAP:
ifr->ifr_tap = ifp->if_tap;
return 0;
}
return (0);
}

View File

@@ -162,6 +162,8 @@ struct ifnet {
__P((struct ifnet *, struct mbuf *));
void (*if_init) /* Init routine */
__P((void *));
int (*if_tap) /* Packet filter routine */
(struct ifnet *, struct ether_header *, struct mbuf *);
struct ifqueue if_snd; /* output queue */
struct ifqueue *if_poll_slowq; /* input queue for slow devices */
};
@@ -369,6 +371,7 @@ struct ifreq {
int ifru_phys;
int ifru_media;
caddr_t ifru_data;
int (*ifru_tap)(struct ifnet *, struct ether_header *, struct mbuf *);
} ifr_ifru;
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
@@ -379,6 +382,7 @@ struct ifreq {
#define ifr_phys ifr_ifru.ifru_phys /* physical wire */
#define ifr_media ifr_ifru.ifru_media /* physical media */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
#define ifr_tap ifr_ifru.ifru_tap /* tap function */
};
struct ifaliasreq {

View File

@@ -483,6 +483,15 @@ ether_input(ifp, eh, m)
if (m->m_flags & (M_BCAST|M_MCAST))
ifp->if_imcasts++;
/*
* RTEMS addition -- allow application to `tap into'
* the incoming packet stream.
*/
if (ifp->if_tap && (*ifp->if_tap)(ifp, eh, m)) {
m_freem(m);
return;
}
ether_type = ntohs(eh->ether_type);
switch (ether_type) {

View File

@@ -83,4 +83,11 @@
#define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */
#define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */
/*
* RTEMS additions for setting/getting `tap' function on incoming packets.
*/
#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */
#define SIOCGIFTAP _IOWR('i', 81, struct ifreq) /* get tap function */
#endif /* !_SYS_SOCKIO_H_ */

View File

@@ -664,6 +664,17 @@ ifioctl(so, cmd, data, p)
}
#endif
/*
* RTEMS additions for setting/getting `tap' function
*/
case SIOCSIFTAP:
ifp->if_tap = ifr->ifr_tap;
return 0;
case SIOCGIFTAP:
ifr->ifr_tap = ifp->if_tap;
return 0;
}
return (0);
}

View File

@@ -162,6 +162,8 @@ struct ifnet {
__P((struct ifnet *, struct mbuf *));
void (*if_init) /* Init routine */
__P((void *));
int (*if_tap) /* Packet filter routine */
(struct ifnet *, struct ether_header *, struct mbuf *);
struct ifqueue if_snd; /* output queue */
struct ifqueue *if_poll_slowq; /* input queue for slow devices */
};
@@ -369,6 +371,7 @@ struct ifreq {
int ifru_phys;
int ifru_media;
caddr_t ifru_data;
int (*ifru_tap)(struct ifnet *, struct ether_header *, struct mbuf *);
} ifr_ifru;
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
@@ -379,6 +382,7 @@ struct ifreq {
#define ifr_phys ifr_ifru.ifru_phys /* physical wire */
#define ifr_media ifr_ifru.ifru_media /* physical media */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
#define ifr_tap ifr_ifru.ifru_tap /* tap function */
};
struct ifaliasreq {

View File

@@ -483,6 +483,15 @@ ether_input(ifp, eh, m)
if (m->m_flags & (M_BCAST|M_MCAST))
ifp->if_imcasts++;
/*
* RTEMS addition -- allow application to `tap into'
* the incoming packet stream.
*/
if (ifp->if_tap && (*ifp->if_tap)(ifp, eh, m)) {
m_freem(m);
return;
}
ether_type = ntohs(eh->ether_type);
switch (ether_type) {

View File

@@ -83,4 +83,11 @@
#define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */
#define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */
/*
* RTEMS additions for setting/getting `tap' function on incoming packets.
*/
#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */
#define SIOCGIFTAP _IOWR('i', 81, struct ifreq) /* get tap function */
#endif /* !_SYS_SOCKIO_H_ */

View File

@@ -83,4 +83,11 @@
#define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */
#define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */
/*
* RTEMS additions for setting/getting `tap' function on incoming packets.
*/
#define SIOCSIFTAP _IOW('i', 80, struct ifreq) /* set tap function */
#define SIOCGIFTAP _IOWR('i', 81, struct ifreq) /* get tap function */
#endif /* !_SYS_SOCKIO_H_ */

View File

@@ -664,6 +664,17 @@ ifioctl(so, cmd, data, p)
}
#endif
/*
* RTEMS additions for setting/getting `tap' function
*/
case SIOCSIFTAP:
ifp->if_tap = ifr->ifr_tap;
return 0;
case SIOCGIFTAP:
ifr->ifr_tap = ifp->if_tap;
return 0;
}
return (0);
}

View File

@@ -162,6 +162,8 @@ struct ifnet {
__P((struct ifnet *, struct mbuf *));
void (*if_init) /* Init routine */
__P((void *));
int (*if_tap) /* Packet filter routine */
(struct ifnet *, struct ether_header *, struct mbuf *);
struct ifqueue if_snd; /* output queue */
struct ifqueue *if_poll_slowq; /* input queue for slow devices */
};
@@ -369,6 +371,7 @@ struct ifreq {
int ifru_phys;
int ifru_media;
caddr_t ifru_data;
int (*ifru_tap)(struct ifnet *, struct ether_header *, struct mbuf *);
} ifr_ifru;
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
@@ -379,6 +382,7 @@ struct ifreq {
#define ifr_phys ifr_ifru.ifru_phys /* physical wire */
#define ifr_media ifr_ifru.ifru_media /* physical media */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
#define ifr_tap ifr_ifru.ifru_tap /* tap function */
};
struct ifaliasreq {

View File

@@ -483,6 +483,15 @@ ether_input(ifp, eh, m)
if (m->m_flags & (M_BCAST|M_MCAST))
ifp->if_imcasts++;
/*
* RTEMS addition -- allow application to `tap into'
* the incoming packet stream.
*/
if (ifp->if_tap && (*ifp->if_tap)(ifp, eh, m)) {
m_freem(m);
return;
}
ether_type = ntohs(eh->ether_type);
switch (ether_type) {