diff options
author | delphij <delphij@FreeBSD.org> | 2009-11-11 21:30:58 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2009-11-11 21:30:58 +0000 |
commit | 13a19ef806aacb68fca8a06969fe760e790cf191 (patch) | |
tree | eea1594231338258764b9d2c6a5b8c04a07d0269 /sys/net | |
parent | 7f8b0bd4a81476d4906f4ec7983d3328593bebde (diff) | |
download | FreeBSD-src-13a19ef806aacb68fca8a06969fe760e790cf191.zip FreeBSD-src-13a19ef806aacb68fca8a06969fe760e790cf191.tar.gz |
Add interface description capability as inspired by OpenBSD.
MFC after: 3 months
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if.c | 41 | ||||
-rw-r--r-- | sys/net/if.h | 2 | ||||
-rw-r--r-- | sys/net/if_var.h | 3 |
3 files changed, 45 insertions, 1 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 55de666..4ba453a 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -463,6 +463,8 @@ if_free_internal(struct ifnet *ifp) #ifdef MAC mac_ifnet_destroy(ifp); #endif /* MAC */ + if (ifp->if_description != NULL) + sbuf_delete(ifp->if_description); IF_AFDATA_DESTROY(ifp); IF_ADDR_LOCK_DESTROY(ifp); ifq_delete(&ifp->if_snd); @@ -2090,6 +2092,45 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) ifr->ifr_phys = ifp->if_physical; break; + case SIOCGIFDESCR: + IF_AFDATA_RLOCK(ifp); + if (ifp->if_description == NULL) + error = ENOMSG; + else + error = copystr(sbuf_data(ifp->if_description), + ifr->ifr_buffer.buffer, + ifr->ifr_buffer.length, NULL); + IF_AFDATA_RUNLOCK(ifp); + break; + + case SIOCSIFDESCR: + error = priv_check(td, PRIV_NET_SETIFDESCR); + if (error) + return (error); + + IF_AFDATA_WLOCK(ifp); + if (ifp->if_description == NULL) { + ifp->if_description = sbuf_new_auto(); + if (ifp->if_description == NULL) { + error = ENOMEM; + IF_AFDATA_WUNLOCK(ifp); + break; + } + } else + sbuf_clear(ifp->if_description); + + if (sbuf_copyin(ifp->if_description, ifr->ifr_buffer.buffer, + ifr->ifr_buffer.length) == -1) + error = EFAULT; + + if (error == 0) { + sbuf_finish(ifp->if_description); + getmicrotime(&ifp->if_lastchange); + } + IF_AFDATA_WUNLOCK(ifp); + + break; + case SIOCSIFFLAGS: error = priv_check(td, PRIV_NET_SETIFFLAGS); if (error) diff --git a/sys/net/if.h b/sys/net/if.h index 857ab7f..89f172b 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -294,6 +294,7 @@ struct ifreq { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; + struct { size_t length; caddr_t buffer; } ifru_buffer; short ifru_flags[2]; short ifru_index; int ifru_jid; @@ -307,6 +308,7 @@ struct ifreq { #define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ +#define ifr_buffer ifr_ifru.ifru_buffer /* user supplied buffer with its length */ #define ifr_flags ifr_ifru.ifru_flags[0] /* flags (low 16 bits) */ #define ifr_flagshigh ifr_ifru.ifru_flags[1] /* flags (high 16 bits) */ #define ifr_jid ifr_ifru.ifru_jid /* jail/vnet */ diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 523b9e8..82e7aab 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -198,6 +198,7 @@ struct ifnet { void *if_pf_kif; void *if_lagg; /* lagg glue */ u_char if_alloctype; /* if_type at time of allocation */ + struct sbuf *if_description; /* interface description */ /* * Spare fields are added so that we can modify sensitive data @@ -205,7 +206,7 @@ struct ifnet { * be used with care where binary compatibility is required. */ char if_cspare[3]; - void *if_pspare[8]; + void *if_pspare[7]; int if_ispare[4]; }; |