Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if.c
| Show First 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | |||||
| #endif /* INET */ | #endif /* INET */ | ||||
| #ifdef INET6 | #ifdef INET6 | ||||
| #include <netinet6/in6_var.h> | #include <netinet6/in6_var.h> | ||||
| #endif /* INET6 */ | #endif /* INET6 */ | ||||
| #endif /* INET || INET6 */ | #endif /* INET || INET6 */ | ||||
| #include <security/mac/mac_framework.h> | #include <security/mac/mac_framework.h> | ||||
| #include <vm/vm_extern.h> | |||||
| /* | /* | ||||
| * Consumers of struct ifreq such as tcpdump assume no pad between ifr_name | * Consumers of struct ifreq such as tcpdump assume no pad between ifr_name | ||||
| * and ifr_ifru when it is used in SIOCGIFCONF. | * and ifr_ifru when it is used in SIOCGIFCONF. | ||||
| */ | */ | ||||
| _Static_assert(sizeof(((struct ifreq *)0)->ifr_name) == | _Static_assert(sizeof(((struct ifreq *)0)->ifr_name) == | ||||
| offsetof(struct ifreq, ifr_ifru), "gap between ifr_name and ifr_ifru"); | offsetof(struct ifreq, ifr_ifru), "gap between ifr_name and ifr_ifru"); | ||||
| __read_mostly epoch_t net_epoch_preempt; | __read_mostly epoch_t net_epoch_preempt; | ||||
| ▲ Show 20 Lines • Show All 1,356 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* | /* | ||||
| * Stores all groups from an interface in memory pointed to by ifgr. | * Stores all groups from an interface in memory pointed to by ifgr. | ||||
| */ | */ | ||||
| static int | static int | ||||
| if_getgroup(struct ifgroupreq *ifgr, struct ifnet *ifp) | if_getgroup(struct ifgroupreq *ifgr, struct ifnet *ifp) | ||||
| { | { | ||||
| int len, error; | struct epoch_tracker et; | ||||
| struct ifg_list *ifgl; | struct ifg_list *ifgl; | ||||
| struct ifg_req ifgrq, *ifgp; | struct ifg_req ifgrq, *ifgp; | ||||
| int len, error; | |||||
| NET_EPOCH_ASSERT(); | |||||
| if (ifgr->ifgr_len == 0) { | if (ifgr->ifgr_len == 0) { | ||||
| NET_EPOCH_ENTER(et); | |||||
| CK_STAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) | CK_STAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) | ||||
| ifgr->ifgr_len += sizeof(struct ifg_req); | ifgr->ifgr_len += sizeof(struct ifg_req); | ||||
| NET_EPOCH_EXIT(et); | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| error = vslock(ifgr->ifgr_groups, ifgr->ifgr_len); | |||||
| if (error != 0) | |||||
| return (error); | |||||
| len = ifgr->ifgr_len; | len = ifgr->ifgr_len; | ||||
emaste: We can move this up and use it in the call to vslock | |||||
| ifgp = ifgr->ifgr_groups; | ifgp = ifgr->ifgr_groups; | ||||
| /* XXX: wire */ | NET_EPOCH_ENTER(et); | ||||
| CK_STAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) { | CK_STAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) { | ||||
| if (len < sizeof(ifgrq)) | if (len < sizeof(ifgrq)) { | ||||
| return (EINVAL); | error = EINVAL; | ||||
| break; | |||||
| } | |||||
| bzero(&ifgrq, sizeof ifgrq); | bzero(&ifgrq, sizeof ifgrq); | ||||
| strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group, | strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group, | ||||
| sizeof(ifgrq.ifgrq_group)); | sizeof(ifgrq.ifgrq_group)); | ||||
| if ((error = copyout(&ifgrq, ifgp, sizeof(struct ifg_req)))) | if ((error = copyout(&ifgrq, ifgp, sizeof(struct ifg_req)))) | ||||
| return (error); | break; | ||||
| len -= sizeof(ifgrq); | len -= sizeof(ifgrq); | ||||
| ifgp++; | ifgp++; | ||||
| } | } | ||||
| NET_EPOCH_EXIT(et); | |||||
| return (0); | vsunlock(ifgr->ifgr_groups, ifgr->ifgr_len); | ||||
| return (error); | |||||
| } | } | ||||
| /* | /* | ||||
| * Stores all members of a group in memory pointed to by igfr | * Stores all members of a group in memory pointed to by igfr | ||||
| */ | */ | ||||
| static int | static int | ||||
| if_getgroupmembers(struct ifgroupreq *ifgr) | if_getgroupmembers(struct ifgroupreq *ifgr) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 1,233 Lines • ▼ Show 20 Lines | case SIOCAIFGROUP: | ||||
| if (strnlen(groupname, IFNAMSIZ) == IFNAMSIZ) | if (strnlen(groupname, IFNAMSIZ) == IFNAMSIZ) | ||||
| return (EINVAL); | return (EINVAL); | ||||
| error = if_addgroup(ifp, groupname); | error = if_addgroup(ifp, groupname); | ||||
| if (error != 0) | if (error != 0) | ||||
| return (error); | return (error); | ||||
| break; | break; | ||||
| } | } | ||||
| case SIOCGIFGROUP: | case SIOCGIFGROUP: | ||||
| { | |||||
| struct epoch_tracker et; | |||||
| NET_EPOCH_ENTER(et); | |||||
| error = if_getgroup((struct ifgroupreq *)data, ifp); | error = if_getgroup((struct ifgroupreq *)data, ifp); | ||||
| NET_EPOCH_EXIT(et); | |||||
| break; | break; | ||||
| } | |||||
| case SIOCDIFGROUP: | case SIOCDIFGROUP: | ||||
| { | { | ||||
| const char *groupname; | const char *groupname; | ||||
| error = priv_check(td, PRIV_NET_DELIFGROUP); | error = priv_check(td, PRIV_NET_DELIFGROUP); | ||||
| if (error) | if (error) | ||||
| return (error); | return (error); | ||||
| ▲ Show 20 Lines • Show All 2,358 Lines • Show Last 20 Lines | |||||
We can move this up and use it in the call to vslock