mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-23 18:25:19 +00:00
Revise network interface cloning to take an optional opaque
parameter that can specify configuration parameters: o rev cloner api's to add optional parameter block o add SIOCCREATE2 that accepts parameter data o rev vlan support to use new api (maintain old code) Reviewed by: arch@
This commit is contained in:
parent
d830256f33
commit
6b7330e2d4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=160195
|
@ -121,7 +121,7 @@ struct pflog_softc pflogif[NPFLOG];
|
|||
|
||||
#ifdef __FreeBSD__
|
||||
static void pflog_clone_destroy(struct ifnet *);
|
||||
static int pflog_clone_create(struct if_clone *, int);
|
||||
static int pflog_clone_create(struct if_clone *, int, caddr_t);
|
||||
#else
|
||||
void pflogattach(int);
|
||||
#endif
|
||||
|
@ -161,7 +161,11 @@ pflog_clone_destroy(struct ifnet *ifp)
|
|||
}
|
||||
|
||||
static int
|
||||
#ifdef __FreeBSD__
|
||||
pflog_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
#else
|
||||
pflog_clone_create(struct if_clone *ifc, int unit)
|
||||
#endif
|
||||
{
|
||||
struct pflog_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
|
|
|
@ -148,7 +148,7 @@ SYSCTL_STRUCT(_net_inet_pfsync, 0, stats, CTLFLAG_RW,
|
|||
*/
|
||||
|
||||
static void pfsync_clone_destroy(struct ifnet *);
|
||||
static int pfsync_clone_create(struct if_clone *, int);
|
||||
static int pfsync_clone_create(struct if_clone *, int, caddr_t params);
|
||||
static void pfsync_senddef(void *);
|
||||
#else
|
||||
void pfsyncattach(int);
|
||||
|
@ -205,7 +205,11 @@ pfsync_clone_destroy(struct ifnet *ifp)
|
|||
}
|
||||
|
||||
static int
|
||||
#ifdef __FreeBSD__
|
||||
pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
#else
|
||||
pfsync_clone_create(struct if_clone *ifc, int unit)
|
||||
#endif
|
||||
{
|
||||
struct pfsync_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
|
|
|
@ -1748,12 +1748,15 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td)
|
|||
|
||||
switch (cmd) {
|
||||
case SIOCIFCREATE:
|
||||
case SIOCIFCREATE2:
|
||||
if ((error = suser(td)) != 0)
|
||||
return (error);
|
||||
return (if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name),
|
||||
cmd == SIOCIFCREATE2 ? ifr->ifr_data : NULL));
|
||||
case SIOCIFDESTROY:
|
||||
if ((error = suser(td)) != 0)
|
||||
return (error);
|
||||
return ((cmd == SIOCIFCREATE) ?
|
||||
if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) :
|
||||
if_clone_destroy(ifr->ifr_name));
|
||||
return if_clone_destroy(ifr->ifr_name);
|
||||
|
||||
case SIOCIFGCLONERS:
|
||||
return (if_clone_list((struct if_clonereq *)data));
|
||||
|
|
|
@ -186,7 +186,7 @@ int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
|
|||
|
||||
uma_zone_t bridge_rtnode_zone;
|
||||
|
||||
static int bridge_clone_create(struct if_clone *, int);
|
||||
static int bridge_clone_create(struct if_clone *, int, caddr_t);
|
||||
static void bridge_clone_destroy(struct ifnet *);
|
||||
|
||||
static int bridge_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
|
@ -454,7 +454,7 @@ SYSCTL_PROC(_net_link_bridge, OID_AUTO, ipfw, CTLTYPE_INT|CTLFLAG_RW,
|
|||
* Create a new bridge instance.
|
||||
*/
|
||||
static int
|
||||
bridge_clone_create(struct if_clone *ifc, int unit)
|
||||
bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
{
|
||||
struct bridge_softc *sc, *sc2;
|
||||
struct ifnet *bifp, *ifp;
|
||||
|
|
|
@ -51,7 +51,8 @@
|
|||
#include <net/route.h>
|
||||
|
||||
static void if_clone_free(struct if_clone *ifc);
|
||||
static int if_clone_createif(struct if_clone *ifc, char *name, size_t len);
|
||||
static int if_clone_createif(struct if_clone *ifc, char *name, size_t len,
|
||||
caddr_t params);
|
||||
static int if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp);
|
||||
|
||||
static struct mtx if_cloners_mtx;
|
||||
|
@ -120,7 +121,7 @@ if_clone_init(void)
|
|||
* Lookup and create a clone network interface.
|
||||
*/
|
||||
int
|
||||
if_clone_create(char *name, size_t len)
|
||||
if_clone_create(char *name, size_t len, caddr_t params)
|
||||
{
|
||||
struct if_clone *ifc;
|
||||
|
||||
|
@ -136,14 +137,14 @@ if_clone_create(char *name, size_t len)
|
|||
if (ifc == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
return (if_clone_createif(ifc, name, len));
|
||||
return (if_clone_createif(ifc, name, len, params));
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a clone network interface.
|
||||
*/
|
||||
static int
|
||||
if_clone_createif(struct if_clone *ifc, char *name, size_t len)
|
||||
if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params)
|
||||
{
|
||||
int err;
|
||||
struct ifnet *ifp;
|
||||
|
@ -151,7 +152,7 @@ if_clone_createif(struct if_clone *ifc, char *name, size_t len)
|
|||
if (ifunit(name) != NULL)
|
||||
return (EEXIST);
|
||||
|
||||
err = (*ifc->ifc_create)(ifc, name, len);
|
||||
err = (*ifc->ifc_create)(ifc, name, len, params);
|
||||
|
||||
if (!err) {
|
||||
ifp = ifunit(name);
|
||||
|
@ -474,7 +475,7 @@ ifc_simple_attach(struct if_clone *ifc)
|
|||
|
||||
for (unit = 0; unit < ifcs->ifcs_minifs; unit++) {
|
||||
snprintf(name, IFNAMSIZ, "%s%d", ifc->ifc_name, unit);
|
||||
err = if_clone_createif(ifc, name, IFNAMSIZ);
|
||||
err = if_clone_createif(ifc, name, IFNAMSIZ, NULL);
|
||||
KASSERT(err == 0,
|
||||
("%s: failed to create required interface %s",
|
||||
__func__, name));
|
||||
|
@ -503,7 +504,7 @@ ifc_simple_match(struct if_clone *ifc, const char *name)
|
|||
}
|
||||
|
||||
int
|
||||
ifc_simple_create(struct if_clone *ifc, char *name, size_t len)
|
||||
ifc_simple_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
|
||||
{
|
||||
char *dp;
|
||||
int wildcard;
|
||||
|
@ -521,7 +522,7 @@ ifc_simple_create(struct if_clone *ifc, char *name, size_t len)
|
|||
if (err != 0)
|
||||
return (err);
|
||||
|
||||
err = ifcs->ifcs_create(ifc, unit);
|
||||
err = ifcs->ifcs_create(ifc, unit, params);
|
||||
if (err != 0) {
|
||||
ifc_free_unit(ifc, unit);
|
||||
return (err);
|
||||
|
|
|
@ -61,7 +61,7 @@ struct if_clone {
|
|||
/* (c) Driver specific cloning functions. Called with no locks held. */
|
||||
void (*ifc_attach)(struct if_clone *);
|
||||
int (*ifc_match)(struct if_clone *, const char *);
|
||||
int (*ifc_create)(struct if_clone *, char *, size_t);
|
||||
int (*ifc_create)(struct if_clone *, char *, size_t, caddr_t);
|
||||
int (*ifc_destroy)(struct if_clone *, struct ifnet *);
|
||||
|
||||
long ifc_refcnt; /* (i) Refrence count. */
|
||||
|
@ -73,7 +73,7 @@ void if_clone_init(void);
|
|||
void if_clone_attach(struct if_clone *);
|
||||
void if_clone_detach(struct if_clone *);
|
||||
|
||||
int if_clone_create(char *, size_t);
|
||||
int if_clone_create(char *, size_t, caddr_t);
|
||||
int if_clone_destroy(const char *);
|
||||
int if_clone_list(struct if_clonereq *);
|
||||
|
||||
|
@ -89,7 +89,7 @@ void ifc_free_unit(struct if_clone *, int);
|
|||
struct ifc_simple_data {
|
||||
int ifcs_minifs; /* minimum number of interfaces */
|
||||
|
||||
int (*ifcs_create)(struct if_clone *, int);
|
||||
int (*ifcs_create)(struct if_clone *, int, caddr_t);
|
||||
void (*ifcs_destroy)(struct ifnet *);
|
||||
};
|
||||
|
||||
|
@ -106,7 +106,7 @@ struct if_clone name##_cloner = \
|
|||
|
||||
void ifc_simple_attach(struct if_clone *);
|
||||
int ifc_simple_match(struct if_clone *, const char *);
|
||||
int ifc_simple_create(struct if_clone *, char *, size_t);
|
||||
int ifc_simple_create(struct if_clone *, char *, size_t, caddr_t);
|
||||
int ifc_simple_destroy(struct if_clone *, struct ifnet *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
|
|
@ -69,7 +69,7 @@ static int discoutput(struct ifnet *, struct mbuf *,
|
|||
struct sockaddr *, struct rtentry *);
|
||||
static void discrtrequest(int, struct rtentry *, struct rt_addrinfo *);
|
||||
static int discioctl(struct ifnet *, u_long, caddr_t);
|
||||
static int disc_clone_create(struct if_clone *, int);
|
||||
static int disc_clone_create(struct if_clone *, int, caddr_t);
|
||||
static void disc_clone_destroy(struct ifnet *);
|
||||
|
||||
static MALLOC_DEFINE(M_DISC, DISCNAME, "Discard interface");
|
||||
|
@ -77,7 +77,7 @@ static MALLOC_DEFINE(M_DISC, DISCNAME, "Discard interface");
|
|||
IFC_SIMPLE_DECLARE(disc, 0);
|
||||
|
||||
static int
|
||||
disc_clone_create(struct if_clone *ifc, int unit)
|
||||
disc_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct disc_softc *sc;
|
||||
|
|
|
@ -98,7 +98,7 @@ static int faithmodevent(module_t, int, void *);
|
|||
|
||||
static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface");
|
||||
|
||||
static int faith_clone_create(struct if_clone *, int);
|
||||
static int faith_clone_create(struct if_clone *, int, caddr_t);
|
||||
static void faith_clone_destroy(struct ifnet *);
|
||||
|
||||
IFC_SIMPLE_DECLARE(faith, 0);
|
||||
|
@ -144,9 +144,10 @@ DECLARE_MODULE(if_faith, faith_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
|
|||
MODULE_VERSION(if_faith, 1);
|
||||
|
||||
static int
|
||||
faith_clone_create(ifc, unit)
|
||||
faith_clone_create(ifc, unit, params)
|
||||
struct if_clone *ifc;
|
||||
int unit;
|
||||
caddr_t params;
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct faith_softc *sc;
|
||||
|
|
|
@ -101,7 +101,7 @@ void (*ng_gif_attach_p)(struct ifnet *ifp);
|
|||
void (*ng_gif_detach_p)(struct ifnet *ifp);
|
||||
|
||||
static void gif_start(struct ifnet *);
|
||||
static int gif_clone_create(struct if_clone *, int);
|
||||
static int gif_clone_create(struct if_clone *, int, caddr_t);
|
||||
static void gif_clone_destroy(struct ifnet *);
|
||||
|
||||
IFC_SIMPLE_DECLARE(gif, 0);
|
||||
|
@ -140,9 +140,10 @@ SYSCTL_INT(_net_link_gif, OID_AUTO, parallel_tunnels, CTLFLAG_RW,
|
|||
¶llel_tunnels, 0, "Allow parallel tunnels?");
|
||||
|
||||
static int
|
||||
gif_clone_create(ifc, unit)
|
||||
gif_clone_create(ifc, unit, params)
|
||||
struct if_clone *ifc;
|
||||
int unit;
|
||||
caddr_t params;
|
||||
{
|
||||
struct gif_softc *sc;
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ static MALLOC_DEFINE(M_GRE, GRENAME, "Generic Routing Encapsulation");
|
|||
|
||||
struct gre_softc_head gre_softc_list;
|
||||
|
||||
static int gre_clone_create(struct if_clone *, int);
|
||||
static int gre_clone_create(struct if_clone *, int, caddr_t);
|
||||
static void gre_clone_destroy(struct ifnet *);
|
||||
static int gre_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
static int gre_output(struct ifnet *, struct mbuf *, struct sockaddr *,
|
||||
|
@ -171,9 +171,10 @@ greattach(void)
|
|||
}
|
||||
|
||||
static int
|
||||
gre_clone_create(ifc, unit)
|
||||
gre_clone_create(ifc, unit, params)
|
||||
struct if_clone *ifc;
|
||||
int unit;
|
||||
caddr_t params;
|
||||
{
|
||||
struct gre_softc *sc;
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ int loioctl(struct ifnet *, u_long, caddr_t);
|
|||
static void lortrequest(int, struct rtentry *, struct rt_addrinfo *);
|
||||
int looutput(struct ifnet *ifp, struct mbuf *m,
|
||||
struct sockaddr *dst, struct rtentry *rt);
|
||||
static int lo_clone_create(struct if_clone *, int);
|
||||
static int lo_clone_create(struct if_clone *, int, caddr_t);
|
||||
static void lo_clone_destroy(struct ifnet *);
|
||||
|
||||
struct ifnet *loif = NULL; /* Used externally */
|
||||
|
@ -134,9 +134,10 @@ lo_clone_destroy(ifp)
|
|||
}
|
||||
|
||||
static int
|
||||
lo_clone_create(ifc, unit)
|
||||
lo_clone_create(ifc, unit, params)
|
||||
struct if_clone *ifc;
|
||||
int unit;
|
||||
caddr_t params;
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct lo_softc *sc;
|
||||
|
|
|
@ -157,7 +157,7 @@ static void ppp_ccp(struct ppp_softc *, struct mbuf *m, int rcvd);
|
|||
static void ppp_ccp_closed(struct ppp_softc *);
|
||||
static void ppp_inproc(struct ppp_softc *, struct mbuf *);
|
||||
static void pppdumpm(struct mbuf *m0);
|
||||
static int ppp_clone_create(struct if_clone *, int);
|
||||
static int ppp_clone_create(struct if_clone *, int, caddr_t);
|
||||
static void ppp_clone_destroy(struct ifnet *);
|
||||
|
||||
IFC_SIMPLE_DECLARE(ppp, 0);
|
||||
|
@ -205,7 +205,7 @@ static struct compressor *ppp_compressors[8] = {
|
|||
#endif /* PPP_COMPRESS */
|
||||
|
||||
static int
|
||||
ppp_clone_create(struct if_clone *ifc, int unit)
|
||||
ppp_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct ppp_softc *sc;
|
||||
|
@ -328,7 +328,7 @@ pppalloc(pid)
|
|||
/* Try to clone an interface if we don't have a free one */
|
||||
if (sc == NULL) {
|
||||
strcpy(tmpname, PPPNAME);
|
||||
if (if_clone_create(tmpname, sizeof(tmpname)) != 0)
|
||||
if (if_clone_create(tmpname, sizeof(tmpname), (caddr_t) 0) != 0)
|
||||
return NULL;
|
||||
ifp = ifunit(tmpname);
|
||||
if (ifp == NULL)
|
||||
|
|
|
@ -177,7 +177,7 @@ static void stf_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
|
|||
static int stf_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
|
||||
static int stf_clone_match(struct if_clone *, const char *);
|
||||
static int stf_clone_create(struct if_clone *, char *, size_t);
|
||||
static int stf_clone_create(struct if_clone *, char *, size_t, caddr_t);
|
||||
static int stf_clone_destroy(struct if_clone *, struct ifnet *);
|
||||
struct if_clone stf_cloner = IFC_CLONE_INITIALIZER(STFNAME, NULL, 0,
|
||||
NULL, stf_clone_match, stf_clone_create, stf_clone_destroy);
|
||||
|
@ -196,7 +196,7 @@ stf_clone_match(struct if_clone *ifc, const char *name)
|
|||
}
|
||||
|
||||
static int
|
||||
stf_clone_create(struct if_clone *ifc, char *name, size_t len)
|
||||
stf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
|
||||
{
|
||||
int err, unit;
|
||||
struct stf_softc *sc;
|
||||
|
|
|
@ -192,7 +192,7 @@ static void vlan_trunk_capabilities(struct ifnet *ifp);
|
|||
static struct ifnet *vlan_clone_match_ethertag(struct if_clone *,
|
||||
const char *, int *);
|
||||
static int vlan_clone_match(struct if_clone *, const char *);
|
||||
static int vlan_clone_create(struct if_clone *, char *, size_t);
|
||||
static int vlan_clone_create(struct if_clone *, char *, size_t, caddr_t);
|
||||
static int vlan_clone_destroy(struct if_clone *, struct ifnet *);
|
||||
|
||||
static void vlan_ifdetach(void *arg, struct ifnet *ifp);
|
||||
|
@ -615,7 +615,7 @@ vlan_clone_match(struct if_clone *ifc, const char *name)
|
|||
}
|
||||
|
||||
static int
|
||||
vlan_clone_create(struct if_clone *ifc, char *name, size_t len)
|
||||
vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
|
||||
{
|
||||
char *dp;
|
||||
int wildcard;
|
||||
|
@ -626,9 +626,39 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len)
|
|||
struct ifvlan *ifv;
|
||||
struct ifnet *ifp;
|
||||
struct ifnet *p;
|
||||
struct vlanreq vlr;
|
||||
static const u_char eaddr[6]; /* 00:00:00:00:00:00 */
|
||||
|
||||
if ((p = vlan_clone_match_ethertag(ifc, name, &tag)) != NULL) {
|
||||
/*
|
||||
* There are 3 (ugh) ways to specify the cloned device:
|
||||
* o pass a parameter block with the clone request.
|
||||
* o specify parameters in the text of the clone device name
|
||||
* o specify no parameters and get an unattached device that
|
||||
* must be configured separately.
|
||||
* The first technique is preferred; the latter two are
|
||||
* supported for backwards compatibilty.
|
||||
*/
|
||||
if (params) {
|
||||
error = copyin(params, &vlr, sizeof(vlr));
|
||||
if (error)
|
||||
return error;
|
||||
p = ifunit(vlr.vlr_parent);
|
||||
if (p == NULL)
|
||||
return ENXIO;
|
||||
/*
|
||||
* Don't let the caller set up a VLAN tag with
|
||||
* anything except VLID bits.
|
||||
*/
|
||||
if (vlr.vlr_tag & ~EVL_VLID_MASK)
|
||||
return (EINVAL);
|
||||
error = ifc_name2unit(name, &unit);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
ethertag = 1;
|
||||
tag = vlr.vlr_tag;
|
||||
wildcard = (unit < 0);
|
||||
} else if ((p = vlan_clone_match_ethertag(ifc, name, &tag)) != NULL) {
|
||||
ethertag = 1;
|
||||
unit = -1;
|
||||
wildcard = 0;
|
||||
|
|
|
@ -189,7 +189,7 @@ static int carp_hmac_verify(struct carp_softc *, u_int32_t *,
|
|||
unsigned char *);
|
||||
static void carp_setroute(struct carp_softc *, int);
|
||||
static void carp_input_c(struct mbuf *, struct carp_header *, sa_family_t);
|
||||
static int carp_clone_create(struct if_clone *, int);
|
||||
static int carp_clone_create(struct if_clone *, int, caddr_t);
|
||||
static void carp_clone_destroy(struct ifnet *);
|
||||
static void carpdetach(struct carp_softc *);
|
||||
static int carp_prepare_ad(struct mbuf *, struct carp_softc *,
|
||||
|
@ -352,7 +352,7 @@ carp_setroute(struct carp_softc *sc, int cmd)
|
|||
}
|
||||
|
||||
static int
|
||||
carp_clone_create(struct if_clone *ifc, int unit)
|
||||
carp_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
{
|
||||
|
||||
struct carp_softc *sc;
|
||||
|
|
|
@ -114,6 +114,7 @@
|
|||
parameters */
|
||||
|
||||
#define SIOCIFCREATE _IOWR('i', 122, struct ifreq) /* create clone if */
|
||||
#define SIOCIFCREATE2 _IOWR('i', 124, struct ifreq) /* create clone if */
|
||||
#define SIOCIFDESTROY _IOW('i', 121, struct ifreq) /* destroy clone if */
|
||||
#define SIOCIFGCLONERS _IOWR('i', 120, struct if_clonereq) /* get cloners */
|
||||
|
||||
|
|
Loading…
Reference in a new issue