Apparently, this leads to some funny results.  There are a bunch of
prototypes under "ifndef _KERNEL":

#ifndef _KERNEL
__BEGIN_DECLS
unsigned int if_nametoindex(const char *);
char    *if_indextoname(unsigned int, char *);
struct  if_nameindex *if_nameindex(void);
void    if_freenameindex(struct if_nameindex *);
__END_DECLS
#endif

That, when hidden by the netstat (it does #define _KERNEL) produces
undefined symbols at linkage time:

    % nm ./obj/netstat | grep if_indextoname
             U if_indextoname

Which results in all kinds of crashes :(

I can't think of any way to resolve it other than including if.h
twice: once with _KERNEL, once without.  But that's going to be a
huge overkill for ports.

On Mon, Nov 18, 2013 at 13:24 -0700, Theo de Raadt wrote:
> I prefer something this model of handling the situation, as long as
> the ports tree software handles it well.  (But then again, the other
> way of doing it will cause effects there as well..)
> 
> > As promised here's a take on hiding ifnet via _KERNEL.  This looks
> > a bit simpler.  I've tried not to toss things around that much and
> > have only moved 'ifqueue'.
> > 
> > diff --git sys/net/if.h sys/net/if.h
> > index b7d1b3c..9a14117 100644
> > --- sys/net/if.h
> > +++ sys/net/if.h
> > @@ -58,16 +58,15 @@ void    if_freenameindex(struct if_nameindex *);
> >  __END_DECLS
> >  #endif
> >  
> >  #if __BSD_VISIBLE
> >  
> > +#ifdef _KERNEL
> >  #include <sys/queue.h>
> >  #include <sys/tree.h>
> >  #include <altq/if_altq.h>
> > -#ifdef _KERNEL
> >  #include <net/hfsc.h>
> > -#endif
> >  
> >  /*
> >   * Structures defining a network interface, providing a packet
> >   * transport mechanism (ala level 0 of the PUP protocols).
> >   *
> > @@ -116,10 +115,11 @@ struct if_clone {
> >     int     (*ifc_destroy)(struct ifnet *);
> >  };
> >  
> >  #define    IF_CLONE_INITIALIZER(name, create, destroy)                     
> > \
> >     { { 0 }, name, sizeof(name) - 1, create, destroy }
> > +#endif /* _KERNEL */
> >  
> >  /*
> >   * Structure used to query names of interface cloners.
> >   */
> >  struct if_clonereq {
> > @@ -168,30 +168,10 @@ struct        if_data {
> >     struct  timeval ifi_lastchange; /* last operational state change */
> >  
> >     struct mclpool  ifi_mclpool[MCLPOOLS];
> >  };
> >  
> > -#define IFQ_NQUEUES        8
> > -#define IFQ_MAXPRIO        IFQ_NQUEUES - 1
> > -#define IFQ_DEFPRIO        3
> > -
> > -/*
> > - * Structure defining a queue for a network interface.
> > - * XXX keep in sync with struct ifaltq.
> > - */
> > -struct     ifqueue {
> > -   struct {
> > -           struct  mbuf *head;
> > -           struct  mbuf *tail;
> > -   }                        ifq_q[IFQ_NQUEUES];
> > -   int                      ifq_len;
> > -   int                      ifq_maxlen;
> > -   int                      ifq_drops;
> > -   struct hfsc_if          *ifq_hfsc;
> > -   struct timeout          *ifq_congestion;
> > -};
> > -
> >  /*
> >   * Values for if_link_state.
> >   */
> >  #define LINK_STATE_UNKNOWN 0       /* link unknown */
> >  #define LINK_STATE_INVALID 1       /* link invalid */
> > @@ -214,12 +194,11 @@ struct if_status_description {
> >  };
> >  
> >  #define LINK_STATE_DESC_MATCH(_ifs, _t, _s)                                
> > \
> >     (((_ifs)->ifs_type == (_t) || (_ifs)->ifs_type == 0) &&         \
> >         (_ifs)->ifs_state == (_s))
> > -           
> > -   
> > +
> >  
> >  #define LINK_STATE_DESCRIPTIONS {                                  \
> >     { IFT_ETHER, LINK_STATE_DOWN, "no carrier" },                   \
> >                                                                     \
> >     { IFT_IEEE80211, LINK_STATE_DOWN, "no network" },               \
> > @@ -240,25 +219,46 @@ struct if_status_description {
> >     { 0, LINK_STATE_DOWN, "down" },                                 \
> >     { 0, LINK_STATE_KALIVE_DOWN, "keepalive down" },                \
> >     { 0, 0, NULL }                                                  \
> >  }
> >  
> > -/*
> > - * Structure defining a queue for a network interface.
> > - *
> > - * (Would like to call this struct ``if'', but C isn't PL/1.)
> > - */
> > -TAILQ_HEAD(ifnet_head, ifnet);             /* the actual queue head */
> > -
> >  /* Traditional BSD name for length of interface external name. */
> >  #define    IFNAMSIZ        IF_NAMESIZE
> >  
> >  /*
> >   * Length of interface description, including terminating '\0'.
> >   */
> >  #define    IFDESCRSIZE     64
> >  
> > +#define    IFQ_NQUEUES     8
> > +#define    IFQ_MAXPRIO     IFQ_NQUEUES - 1
> > +#define    IFQ_DEFPRIO     3
> > +
> > +#ifdef _KERNEL
> > +/*
> > + * Structure defining a queue for a network interface.
> > + * XXX keep in sync with struct ifaltq.
> > + */
> > +struct ifqueue {
> > +   struct {
> > +           struct  mbuf *head;
> > +           struct  mbuf *tail;
> > +   }                        ifq_q[IFQ_NQUEUES];
> > +   int                      ifq_len;
> > +   int                      ifq_maxlen;
> > +   int                      ifq_drops;
> > +   struct hfsc_if          *ifq_hfsc;
> > +   struct timeout          *ifq_congestion;
> > +};
> > +
> > +/*
> > + * Structure defining a queue for a network interface.
> > + *
> > + * (Would like to call this struct ``if'', but C isn't PL/1.)
> > + */
> > +TAILQ_HEAD(ifnet_head, ifnet);             /* the actual queue head */
> > +
> >  struct ifnet {                             /* and the entries */
> >     void    *if_softc;              /* lower-level data for this if */
> >     TAILQ_ENTRY(ifnet) if_list;     /* all struct ifnets are chained */
> >     TAILQ_ENTRY(ifnet) if_txlist;   /* list of ifnets ready to tx */
> >     TAILQ_HEAD(, ifaddr) if_addrlist; /* linked list of addresses per if */
> > @@ -330,10 +330,11 @@ struct ifnet {                                /* and 
> > the entries */
> >  #define    if_omcasts      if_data.ifi_omcasts
> >  #define    if_iqdrops      if_data.ifi_iqdrops
> >  #define    if_noproto      if_data.ifi_noproto
> >  #define    if_lastchange   if_data.ifi_lastchange
> >  #define    if_capabilities if_data.ifi_capabilities
> > +#endif /* _KERNEL */
> >  
> >  #define    IFF_UP          0x1             /* interface is up */
> >  #define    IFF_BROADCAST   0x2             /* broadcast address valid */
> >  #define    IFF_DEBUG       0x4             /* turn on debugging */
> >  #define    IFF_LOOPBACK    0x8             /* is a loopback net */
> > @@ -382,10 +383,11 @@ struct ifnet {                                /* and 
> > the entries */
> >  #define    IFCAP_WOL               0x00008000      /* can do wake on lan */
> >  
> >  #define IFCAP_CSUM_MASK            (IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | \
> >      IFCAP_CSUM_UDPv4 | IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6)
> >  
> > +#ifdef _KERNEL
> >  /*
> >   * Output queues (ifp->if_snd) and internetwork datagram level (pup level 
> > 1)
> >   * input routines have queues of messages stored on ifqueue structures
> >   * (defined above).  Entries are added to and deleted from these structures
> >   * by these macros, which should be called with ipl raised to splnet().
> > @@ -460,10 +462,11 @@ do {                                                  
> >                 \
> >  #define    IF_LEN(ifq)             ((ifq)->ifq_len)
> >  #define    IF_IS_EMPTY(ifq)        ((ifq)->ifq_len == 0)
> >  
> >  #define    IFQ_MAXLEN      256
> >  #define    IFNET_SLOWHZ    1               /* granularity is 1 second */
> > +#endif /* _KERNEL */
> >  
> >  /* symbolic names for terminal (per-protocol) CTL_IFQ_ nodes */
> >  #define IFQCTL_LEN 1
> >  #define IFQCTL_MAXLEN 2
> >  #define IFQCTL_DROPS 3
> > @@ -477,10 +480,11 @@ do {                                                  
> >                 \
> >     { "maxlen", CTLTYPE_INT }, \
> >     { "drops", CTLTYPE_INT }, \
> >     { "congestion", CTLTYPE_INT }, \
> >  }
> >  
> > +#ifdef _KERNEL
> >  /*
> >   * The ifaddr structure contains information about one address
> >   * of an interface.  They are maintained by the different address families,
> >   * are allocated and attached when an address is set, and are linked
> >   * together so all addresses for an interface can be located.
> > @@ -505,10 +509,11 @@ struct ifaddr_item {
> >     struct sockaddr         *ifai_addr;
> >     struct ifaddr           *ifai_ifa;
> >     struct ifaddr_item      *ifai_next;
> >     u_int                    ifai_rdomain;
> >  };
> > +#endif /* _KERNEL */
> >  
> >  /*
> >   * Message format for use in obtaining information about interfaces
> >   * from sysctl and the routing socket.
> >   */
> > @@ -543,11 +548,10 @@ struct ifa_msghdr {
> >     int     ifam_addrs;     /* like rtm_addrs */
> >     int     ifam_flags;     /* value of ifa_flags */
> >     int     ifam_metric;    /* value of ifa_metric */
> >  };
> >  
> > -
> >  /*
> >   * Message format announcing the arrival or departure of a network 
> > interface.
> >   */
> >  struct if_announcemsghdr {
> >     u_short ifan_msglen;    /* to skip over non-understood messages */
> > @@ -567,10 +571,11 @@ struct if_announcemsghdr {
> >   */
> >  
> >  #define    IFG_ALL         "all"           /* group contains all 
> > interfaces */
> >  #define    IFG_EGRESS      "egress"        /* if(s) default route(s) point 
> > to */
> >  
> > +#ifdef _KERNEL
> >  struct ifg_group {
> >     char                             ifg_group[IFNAMSIZ];
> >     u_int                            ifg_refcnt;
> >     caddr_t                          ifg_pf_kif;
> >     int                              ifg_carp_demoted;
> > @@ -585,10 +590,11 @@ struct ifg_member {
> >  
> >  struct ifg_list {
> >     struct ifg_group        *ifgl_group;
> >     TAILQ_ENTRY(ifg_list)    ifgl_next;
> >  };
> > +#endif /* _KERNEL */
> >  
> >  struct ifg_req {
> >     union {
> >             char                     ifgrqu_group[IFNAMSIZ];
> >             char                     ifgrqu_member[IFNAMSIZ];
> > diff --git usr.bin/netstat/if.c usr.bin/netstat/if.c
> > index 1cc7e07..96d56b4 100644
> > --- usr.bin/netstat/if.c
> > +++ usr.bin/netstat/if.c
> > @@ -35,11 +35,13 @@
> >  #include <sys/ioctl.h>
> >  #include <sys/protosw.h>
> >  #include <sys/socket.h>
> >  #include <sys/sysctl.h>
> >  
> > +#define _KERNEL
> >  #include <net/if.h>
> > +#undef _KERNEL
> >  #include <net/if_dl.h>
> >  #include <net/if_types.h>
> >  #include <net/route.h>
> >  #include <netinet/in.h>
> >  #include <netinet/in_var.h>
> > diff --git usr.bin/netstat/mroute6.c usr.bin/netstat/mroute6.c
> > index d92c15f..7185260 100644
> > --- usr.bin/netstat/mroute6.c
> > +++ usr.bin/netstat/mroute6.c
> > @@ -69,11 +69,13 @@
> >  #include <sys/socket.h>
> >  #include <sys/socketvar.h>
> >  #include <sys/protosw.h>
> >  #include <sys/sysctl.h>
> >  
> > +#define _KERNEL 1
> >  #include <net/if.h>
> > +#undef _KERNEL
> >  
> >  #include <netinet/in.h>
> >  
> >  #define _KERNEL 1
> >  #include <netinet6/ip6_mroute.h>
> > diff --git usr.bin/netstat/net80211.c usr.bin/netstat/net80211.c
> > index 8f34d06..5fdb480 100644
> > --- usr.bin/netstat/net80211.c
> > +++ usr.bin/netstat/net80211.c
> > @@ -20,11 +20,13 @@
> >  #include <sys/time.h>
> >  #include <sys/socket.h>
> >  #include <sys/file.h>
> >  #include <sys/ioctl.h>
> >  
> > +#define _KERNEL
> >  #include <net/if.h>
> > +#undef _KERNEL
> >  
> >  #include <netinet/in.h>
> >  #include <netinet/in_systm.h>
> >  #include <netinet/if_ether.h>
> >  
> > diff --git usr.bin/netstat/route.c usr.bin/netstat/route.c
> > index fc5281d..c475bdf 100644
> > --- usr.bin/netstat/route.c
> > +++ usr.bin/netstat/route.c
> > @@ -32,11 +32,13 @@
> >  
> >  #include <sys/param.h>
> >  #include <sys/protosw.h>
> >  #include <sys/socket.h>
> >  
> > +#define _KERNEL
> >  #include <net/if.h>
> > +#undef _KERNEL
> >  #include <net/if_dl.h>
> >  #include <net/if_types.h>
> >  #define _KERNEL
> >  #include <net/route.h>
> >  #undef _KERNEL
> > diff --git usr.bin/netstat/show.c usr.bin/netstat/show.c
> > index 67295e3..cbc76bb 100644
> > --- usr.bin/netstat/show.c
> > +++ usr.bin/netstat/show.c
> > @@ -33,11 +33,13 @@
> >  #include <sys/param.h>
> >  #include <sys/protosw.h>
> >  #include <sys/socket.h>
> >  #include <sys/sysctl.h>
> >  
> > +#define _KERNEL
> >  #include <net/if.h>
> > +#undef _KERNEL
> >  #include <net/if_dl.h>
> >  #include <net/if_types.h>
> >  #include <net/pfkeyv2.h>
> >  #include <net/route.h>
> >  #include <netinet/in.h>
> > diff --git usr.sbin/snmpd/snmpd.h usr.sbin/snmpd/snmpd.h
> > index 6a84df3..1dec598 100644
> > --- usr.sbin/snmpd/snmpd.h
> > +++ usr.sbin/snmpd/snmpd.h
> > @@ -215,10 +215,30 @@ struct kif {
> >     struct if_data           if_data;
> >     u_long                   if_ticks;
> >     int                      if_flags;
> >     u_short                  if_index;
> >  };
> > +#define    if_mtu          if_data.ifi_mtu
> > +#define    if_type         if_data.ifi_type
> > +#define    if_addrlen      if_data.ifi_addrlen
> > +#define    if_hdrlen       if_data.ifi_hdrlen
> > +#define    if_metric       if_data.ifi_metric
> > +#define    if_link_state   if_data.ifi_link_state
> > +#define    if_baudrate     if_data.ifi_baudrate
> > +#define    if_ipackets     if_data.ifi_ipackets
> > +#define    if_ierrors      if_data.ifi_ierrors
> > +#define    if_opackets     if_data.ifi_opackets
> > +#define    if_oerrors      if_data.ifi_oerrors
> > +#define    if_collisions   if_data.ifi_collisions
> > +#define    if_ibytes       if_data.ifi_ibytes
> > +#define    if_obytes       if_data.ifi_obytes
> > +#define    if_imcasts      if_data.ifi_imcasts
> > +#define    if_omcasts      if_data.ifi_omcasts
> > +#define    if_iqdrops      if_data.ifi_iqdrops
> > +#define    if_noproto      if_data.ifi_noproto
> > +#define    if_lastchange   if_data.ifi_lastchange
> > +#define    if_capabilities if_data.ifi_capabilities
> >  
> >  #define F_CONNECTED                0x0001
> >  #define F_STATIC           0x0002
> >  #define F_BLACKHOLE                0x0004
> >  #define F_REJECT           0x0008
> > 
> 

Reply via email to