Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/raw_ip.c
Show First 20 Lines • Show All 557 Lines • ▼ Show 20 Lines | |||||
* When adding new socket options here, make sure to add access control | * When adding new socket options here, make sure to add access control | ||||
* checks here as necessary. | * checks here as necessary. | ||||
* | * | ||||
* XXX-BZ inp locking? | * XXX-BZ inp locking? | ||||
*/ | */ | ||||
int | int | ||||
rip_ctloutput(struct socket *so, struct sockopt *sopt) | rip_ctloutput(struct socket *so, struct sockopt *sopt) | ||||
{ | { | ||||
struct inpcb *inp = sotoinpcb(so); | struct inpcb *inp; | ||||
int error, optval; | int optval; | ||||
int error = 0; | |||||
bool wlock = false; | |||||
SOCK_LOCK(so); | |||||
inp = sotoinpcb(so); | |||||
if (inp == NULL) { | |||||
SOCK_UNLOCK(so); | |||||
return ENOTCONN; | |||||
} | |||||
in_pcbref(inp); | |||||
SOCK_UNLOCK(so); | |||||
if (sopt->sopt_level != IPPROTO_IP) { | if (sopt->sopt_level != IPPROTO_IP) { | ||||
if ((sopt->sopt_level == SOL_SOCKET) && | if ((sopt->sopt_level == SOL_SOCKET) && | ||||
(sopt->sopt_name == SO_SETFIB)) { | (sopt->sopt_name == SO_SETFIB)) { | ||||
inp->inp_inc.inc_fibnum = so->so_fibnum; | inp->inp_inc.inc_fibnum = so->so_fibnum; | ||||
return (0); | goto done; | ||||
} | } | ||||
return (EINVAL); | error = EINVAL; | ||||
goto done; | |||||
} | } | ||||
error = 0; | |||||
switch (sopt->sopt_dir) { | switch (sopt->sopt_dir) { | ||||
case SOPT_GET: | case SOPT_GET: | ||||
switch (sopt->sopt_name) { | switch (sopt->sopt_name) { | ||||
case IP_HDRINCL: | case IP_HDRINCL: | ||||
optval = inp->inp_flags & INP_HDRINCL; | optval = inp->inp_flags & INP_HDRINCL; | ||||
error = sooptcopyout(sopt, &optval, sizeof optval); | error = sooptcopyout(sopt, &optval, sizeof optval); | ||||
break; | break; | ||||
Show All 27 Lines | case SOPT_GET: | ||||
case MRT_VERSION: | case MRT_VERSION: | ||||
case MRT_ASSERT: | case MRT_ASSERT: | ||||
case MRT_API_SUPPORT: | case MRT_API_SUPPORT: | ||||
case MRT_API_CONFIG: | case MRT_API_CONFIG: | ||||
case MRT_ADD_BW_UPCALL: | case MRT_ADD_BW_UPCALL: | ||||
case MRT_DEL_BW_UPCALL: | case MRT_DEL_BW_UPCALL: | ||||
error = priv_check(curthread, PRIV_NETINET_MROUTE); | error = priv_check(curthread, PRIV_NETINET_MROUTE); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | break; | ||||
error = ip_mrouter_get ? ip_mrouter_get(so, sopt) : | error = ip_mrouter_get ? ip_mrouter_get(so, sopt) : | ||||
EOPNOTSUPP; | EOPNOTSUPP; | ||||
break; | break; | ||||
default: | default: | ||||
error = ip_ctloutput(so, sopt); | error = ip_ctloutput(so, sopt); | ||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
case SOPT_SET: | case SOPT_SET: | ||||
switch (sopt->sopt_name) { | switch (sopt->sopt_name) { | ||||
case IP_HDRINCL: | case IP_HDRINCL: | ||||
error = sooptcopyin(sopt, &optval, sizeof optval, | error = sooptcopyin(sopt, &optval, sizeof optval, | ||||
sizeof optval); | sizeof optval); | ||||
if (error) | if (error) | ||||
break; | break; | ||||
INP_WLOCK(inp); | |||||
wlock = true; | |||||
if (optval) | if (optval) | ||||
inp->inp_flags |= INP_HDRINCL; | inp->inp_flags |= INP_HDRINCL; | ||||
else | else | ||||
inp->inp_flags &= ~INP_HDRINCL; | inp->inp_flags &= ~INP_HDRINCL; | ||||
break; | break; | ||||
case IP_FW3: /* generic ipfw v.3 functions */ | case IP_FW3: /* generic ipfw v.3 functions */ | ||||
case IP_FW_ADD: | case IP_FW_ADD: | ||||
Show All 20 Lines | case IP_DUMMYNET_FLUSH: | ||||
error = ip_dn_ctl_ptr(sopt); | error = ip_dn_ctl_ptr(sopt); | ||||
else | else | ||||
error = ENOPROTOOPT ; | error = ENOPROTOOPT ; | ||||
break ; | break ; | ||||
case IP_RSVP_ON: | case IP_RSVP_ON: | ||||
error = priv_check(curthread, PRIV_NETINET_MROUTE); | error = priv_check(curthread, PRIV_NETINET_MROUTE); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | break; | ||||
error = ip_rsvp_init(so); | error = ip_rsvp_init(so); | ||||
break; | break; | ||||
case IP_RSVP_OFF: | case IP_RSVP_OFF: | ||||
error = priv_check(curthread, PRIV_NETINET_MROUTE); | error = priv_check(curthread, PRIV_NETINET_MROUTE); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | break; | ||||
error = ip_rsvp_done(); | error = ip_rsvp_done(); | ||||
break; | break; | ||||
case IP_RSVP_VIF_ON: | case IP_RSVP_VIF_ON: | ||||
case IP_RSVP_VIF_OFF: | case IP_RSVP_VIF_OFF: | ||||
error = priv_check(curthread, PRIV_NETINET_MROUTE); | error = priv_check(curthread, PRIV_NETINET_MROUTE); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | break; | ||||
error = ip_rsvp_vif ? | error = ip_rsvp_vif ? | ||||
ip_rsvp_vif(so, sopt) : EINVAL; | ip_rsvp_vif(so, sopt) : EINVAL; | ||||
break; | break; | ||||
case MRT_INIT: | case MRT_INIT: | ||||
case MRT_DONE: | case MRT_DONE: | ||||
case MRT_ADD_VIF: | case MRT_ADD_VIF: | ||||
case MRT_DEL_VIF: | case MRT_DEL_VIF: | ||||
case MRT_ADD_MFC: | case MRT_ADD_MFC: | ||||
case MRT_DEL_MFC: | case MRT_DEL_MFC: | ||||
case MRT_VERSION: | case MRT_VERSION: | ||||
case MRT_ASSERT: | case MRT_ASSERT: | ||||
case MRT_API_SUPPORT: | case MRT_API_SUPPORT: | ||||
case MRT_API_CONFIG: | case MRT_API_CONFIG: | ||||
case MRT_ADD_BW_UPCALL: | case MRT_ADD_BW_UPCALL: | ||||
case MRT_DEL_BW_UPCALL: | case MRT_DEL_BW_UPCALL: | ||||
error = priv_check(curthread, PRIV_NETINET_MROUTE); | error = priv_check(curthread, PRIV_NETINET_MROUTE); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | break; | ||||
error = ip_mrouter_set ? ip_mrouter_set(so, sopt) : | error = ip_mrouter_set ? ip_mrouter_set(so, sopt) : | ||||
EOPNOTSUPP; | EOPNOTSUPP; | ||||
break; | break; | ||||
default: | default: | ||||
error = ip_ctloutput(so, sopt); | error = ip_ctloutput(so, sopt); | ||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
done: | |||||
if (!wlock) | |||||
INP_WLOCK(inp); | |||||
if (!in_pcbrele_wlocked(inp)) | |||||
INP_WUNLOCK(inp); | |||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* This function exists solely to receive the PRC_IFDOWN messages which are | * This function exists solely to receive the PRC_IFDOWN messages which are | ||||
* sent by if_down(). It looks for an ifaddr whose ifa_addr is sa, and calls | * sent by if_down(). It looks for an ifaddr whose ifa_addr is sa, and calls | ||||
* in_ifadown() to remove all routes corresponding to that address. It also | * in_ifadown() to remove all routes corresponding to that address. It also | ||||
▲ Show 20 Lines • Show All 405 Lines • Show Last 20 Lines |