diff --git a/sys/net/if.c b/sys/net/if.c --- a/sys/net/if.c +++ b/sys/net/if.c @@ -279,7 +279,7 @@ static int if_requestencap_default(struct ifnet *, struct if_encap_req *); static void if_route(struct ifnet *, int flag, int fam); static int if_setflag(struct ifnet *, int, int, int *, int); -static int if_transmit(struct ifnet *ifp, struct mbuf *m); +static int if_transmit_default(struct ifnet *ifp, struct mbuf *m); static void if_unroute(struct ifnet *, int flag, int fam); static int if_delmulti_locked(struct ifnet *, struct ifmultiaddr *, int); static void do_link_state_change(void *, int); @@ -421,13 +421,13 @@ */ static void -if_init(void *arg __unused) +if_init_table(void *arg __unused) { ifindex_table = malloc(if_indexlim * sizeof(*ifindex_table), M_IFNET, M_WAITOK | M_ZERO); } -SYSINIT(if_init, SI_SUB_INIT_IF, SI_ORDER_SECOND, if_init, NULL); +SYSINIT(if_init, SI_SUB_INIT_IF, SI_ORDER_SECOND, if_init_table, NULL); static void vnet_if_init(const void *unused __unused) @@ -854,7 +854,7 @@ (ifp->if_transmit != NULL && ifp->if_qflush != NULL), ("transmit and qflush must both either be set or both be NULL")); if (ifp->if_transmit == NULL) { - ifp->if_transmit = if_transmit; + ifp->if_transmit = if_transmit_default; ifp->if_qflush = if_qflush; } if (ifp->if_input == NULL) @@ -4110,7 +4110,7 @@ * that have not implemented it */ static int -if_transmit(struct ifnet *ifp, struct mbuf *m) +if_transmit_default(struct ifnet *ifp, struct mbuf *m) { int error; @@ -4242,12 +4242,53 @@ return (0); } +int +if_setcapabilities2(if_t ifp, int capabilities) +{ + ((struct ifnet *)ifp)->if_capabilities2 = capabilities; + return (0); +} + +int +if_setcapabilities2bit(if_t ifp, int setbit, int clearbit) +{ + ((struct ifnet *)ifp)->if_capabilities2 |= setbit; + ((struct ifnet *)ifp)->if_capabilities2 &= ~clearbit; + + return (0); +} + +int +if_getcapabilities2(if_t ifp) +{ + return ((struct ifnet *)ifp)->if_capabilities2; +} + +int +if_setcapenable2(if_t ifp, int capabilities) +{ + ((struct ifnet *)ifp)->if_capenable2 = capabilities; + return (0); +} + const char * if_getdname(if_t ifp) { return ((struct ifnet *)ifp)->if_dname; } +void +if_setdname(if_t ifp, const char *dname) +{ + ((struct ifnet *)ifp)->if_dname = dname; +} + +char * +if_name(if_t ifp) +{ + return ((struct ifnet *)ifp)->if_xname; +} + int if_togglecapenable(if_t ifp, int togglecap) { @@ -4261,6 +4302,12 @@ return ((struct ifnet *)ifp)->if_capenable; } +int +if_getindex(if_t ifp) +{ + return ((struct ifnet *)ifp)->if_index; +} + void if_setdescr(if_t ifp, char *descrbuf) { @@ -4285,6 +4332,12 @@ free(descrbuf, M_IFDESCR); } +int +if_getalloctype(if_t ifp) +{ + return ((struct ifnet *)ifp)->if_alloctype; +} + /* * This is largely undesirable because it ties ifnet to a device, but does * provide flexiblity for an embedded product vendor. Should be used with @@ -4371,6 +4424,13 @@ return ((struct ifnet *)ifp)->if_hwassist; } +int +if_togglehwassist(if_t ifp, int toggle_bits) +{ + ((struct ifnet *)ifp)->if_hwassist ^= toggle_bits; + return (0); +} + int if_setmtu(if_t ifp, int mtu) { @@ -4480,6 +4540,27 @@ return (count); } +u_int +if_foreach_addr_type(if_t ifp, int type, if_addr_cb_t cb, void *cb_arg) +{ + struct epoch_tracker et; + struct ifaddr *ifa; + u_int count; + + MPASS(cb); + + count = 0; + NET_EPOCH_ENTER(et); + CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { + if (ifa->ifa_addr->sa_family != type) + continue; + count += (*cb)(cb_arg, ifa, count); + } + NET_EPOCH_EXIT(et); + + return (count); +} + int if_setsoftc(if_t ifp, void *softc) { @@ -4554,6 +4635,13 @@ return ((struct ifnet *)ifp)->if_vlantrunk != NULL?1:0; } +int +if_init(if_t ifp) +{ + (*((struct ifnet *)ifp)->if_init)((struct ifnet *)ifp); + return (0); +} + int if_input(if_t ifp, struct mbuf* sendmp) { @@ -4562,6 +4650,13 @@ } +int +if_transmit(if_t ifp, struct mbuf *m) +{ + (*((struct ifnet *)ifp)->if_transmit)((struct ifnet *)ifp, m); + return (0); +} + struct mbuf * if_dequeue(if_t ifp) { @@ -4666,19 +4761,25 @@ } void -if_setinitfn(if_t ifp, void (*init_fn)(void *)) +if_setinitfn(if_t ifp, if_init_fn_t init_fn) { ((struct ifnet *)ifp)->if_init = init_fn; } void -if_setioctlfn(if_t ifp, int (*ioctl_fn)(if_t, u_long, caddr_t)) +if_setinputfn(if_t ifp, if_input_fn_t input_fn) +{ + ((struct ifnet *)ifp)->if_input = input_fn; +} + +void +if_setioctlfn(if_t ifp, if_ioctl_fn_t ioctl_fn) { ((struct ifnet *)ifp)->if_ioctl = (void *)ioctl_fn; } void -if_setstartfn(if_t ifp, void (*start_fn)(if_t)) +if_setstartfn(if_t ifp, if_start_fn_t start_fn) { ((struct ifnet *)ifp)->if_start = (void *)start_fn; } @@ -4689,12 +4790,19 @@ ((struct ifnet *)ifp)->if_transmit = start_fn; } -void if_setqflushfn(if_t ifp, if_qflush_fn_t flush_fn) +void +if_setqflushfn(if_t ifp, if_qflush_fn_t flush_fn) { ((struct ifnet *)ifp)->if_qflush = flush_fn; } +void +if_setsndtagallocfn(if_t ifp, if_snd_tag_alloc_t alloc_fn) +{ + ((struct ifnet *)ifp)->if_snd_tag_alloc = alloc_fn; +} + void if_setgetcounterfn(if_t ifp, if_get_counter_t fn) { diff --git a/sys/net/if_var.h b/sys/net/if_var.h --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -129,6 +129,9 @@ typedef void (*if_start_fn_t)(if_t); typedef int (*if_ioctl_fn_t)(if_t, u_long, caddr_t); typedef void (*if_init_fn_t)(void *); +typedef void (*if_input_fn_t)(struct ifnet *, struct mbuf *); +typedef int (*if_output_fn_t) + (struct ifnet *, struct mbuf *, const struct sockaddr *, struct route *); typedef void (*if_qflush_fn_t)(if_t); typedef int (*if_transmit_fn_t)(if_t, struct mbuf *); typedef uint64_t (*if_get_counter_t)(if_t, ift_counter); @@ -402,11 +405,8 @@ struct netmap_adapter *if_netmap; /* netmap(4) softc */ /* Various procedures of the layer2 encapsulation and drivers. */ - int (*if_output) /* output routine (enqueue) */ - (struct ifnet *, struct mbuf *, const struct sockaddr *, - struct route *); - void (*if_input) /* input routine (from h/w driver) */ - (struct ifnet *, struct mbuf *); + if_output_fn_t if_output; /* output routine (enqueue) */ + if_input_fn_t if_input; /* input routine (from h/w driver) */ struct mbuf *(*if_bridge_input)(struct ifnet *, struct mbuf *); int (*if_bridge_output)(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); @@ -477,9 +477,6 @@ int if_ispare[4]; /* general use */ }; -/* for compatibility with other BSDs */ -#define if_name(ifp) ((ifp)->if_xname) - #define IF_NODOM 255 /* * Locks for address lists on the network interface. @@ -734,14 +731,24 @@ int if_setcapabilities(if_t ifp, int capabilities); int if_setcapabilitiesbit(if_t ifp, int setbit, int clearbit); int if_getcapabilities(if_t ifp); +int if_setcapabilities2(if_t ifp, int capabilities); +int if_setcapabilities2bit(if_t ifp, int setbit, int clearbit); +int if_getcapabilities2(if_t ifp); int if_togglecapenable(if_t ifp, int togglecap); int if_setcapenable(if_t ifp, int capenable); int if_setcapenablebit(if_t ifp, int setcap, int clearcap); int if_getcapenable(if_t ifp); +int if_setcapenable2(if_t ifp, int capenable); +int if_setcapenable2bit(if_t ifp, int setcap, int clearcap); +int if_getcapenable2(if_t ifp); +int if_getindex(if_t ifp); const char *if_getdname(if_t ifp); +void if_setdname(if_t ifp, const char *name); +char *if_name(if_t ifp); void if_setdescr(if_t ifp, char *descrbuf); char *if_allocdescr(size_t sz, int malloc_flag); void if_freedescr(char *descrbuf); +int if_getalloctype(if_t ifp); int if_setdev(if_t ifp, void *dev); int if_setdrvflagbits(if_t ifp, int if_setflags, int clear_flags); int if_getdrvflags(if_t ifp); @@ -750,6 +757,7 @@ int if_sethwassistbits(if_t ifp, int toset, int toclear); int if_sethwassist(if_t ifp, int hwassist_bit); int if_gethwassist(if_t ifp); +int if_togglehwassist(if_t ifp, int toggle_bits); int if_setsoftc(if_t ifp, void *softc); void *if_getsoftc(if_t ifp); int if_setflags(if_t ifp, int flags); @@ -781,6 +789,8 @@ void if_bpfmtap(if_t ifp, struct mbuf *m); void if_etherbpfmtap(if_t ifp, struct mbuf *m); void if_vlancap(if_t ifp); +int if_transmit(if_t ifp, struct mbuf *m); +int if_init(if_t ifp); /* * Traversing through interface address lists. @@ -794,14 +804,20 @@ int if_getamcount(if_t ifp); struct ifaddr * if_getifaddr(if_t ifp); +typedef u_int if_addr_cb_t(void *, struct ifaddr *, u_int); +u_int if_foreach_addr_type(if_t ifp, int type, if_addr_cb_t cb, void *cb_arg); /* Functions */ -void if_setinitfn(if_t ifp, void (*)(void *)); -void if_setioctlfn(if_t ifp, int (*)(if_t, u_long, caddr_t)); +void if_setinitfn(if_t ifp, if_init_fn_t); +void if_setinputfn(if_t ifp, if_input_fn_t); +void if_setioctlfn(if_t ifp, if_ioctl_fn_t); +void if_setoutputfn(if_t ifp, int(*) + (if_t, struct mbuf *, const struct sockaddr *, struct route *)); void if_setstartfn(if_t ifp, void (*)(if_t)); void if_settransmitfn(if_t ifp, if_transmit_fn_t); void if_setqflushfn(if_t ifp, if_qflush_fn_t); void if_setgetcounterfn(if_t ifp, if_get_counter_t); +void if_setsndtagallocfn(if_t ifp, if_snd_tag_alloc_t); /* TSO */ void if_hw_tsomax_common(if_t ifp, struct ifnet_hw_tsomax *);