FreeBSD/sys/netinet/ip_mroute.c
/*
 * Handle MRT setsockopt commands to modify the multicast forwarding tables.
 */
Handle MRT setsockopt commands to modify the multicast forwarding tables.
Handle MRT setsockopt commands to modify the multicast forwarding tables .
static int
X_ip_mrouter_set(struct socket *so, struct sockopt *sopt)
{
    int	error, optval;
    vifi_t	vifi;
    struct	vifctl vifc;
    struct	mfcctl2 mfc;
    struct	bw_upcall bw_upcall;
    uint32_t	i;
    if (so != V_ip_mrouter && sopt->sopt_name != MRT_INIT)
	return EPERM;
    error = 0;
    switch (sopt->sopt_name) {
    case MRT_INIT:
	error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval);
	if (error)
	    break;
	error = ip_mrouter_init(so, optval);
	break;
    case MRT_DONE:
	error = ip_mrouter_done();
	break;
    case MRT_ADD_VIF:
	error = sooptcopyin(sopt, &vifc, sizeof vifc, sizeof vifc);
	if (error)
	    break;
	error = add_vif(&vifc);
	break;
    case MRT_DEL_VIF:
	error = sooptcopyin(sopt, &vifi, sizeof vifi, sizeof vifi);
	if (error)
	    break;
	error = del_vif(vifi);
	break;
    case MRT_ADD_MFC:
    case MRT_DEL_MFC:
	if (sopt->sopt_name == MRT_ADD_MFC &&
		V_mrt_api_config & MRT_API_FLAGS_ALL) {
	    error = sooptcopyin(sopt, &mfc, sizeof(struct mfcctl2),
				sizeof(struct mfcctl2));
	} else {
	    error = sooptcopyin(sopt, &mfc, sizeof(struct mfcctl),
				sizeof(struct mfcctl));
	    bzero((caddr_t)&mfc + sizeof(struct mfcctl),
			sizeof(mfc) - sizeof(struct mfcctl));
	}
	if (error)
	    break;
	if (sopt->sopt_name == MRT_ADD_MFC)
	    error = add_mfc(&mfc);
	else
	    error = del_mfc(&mfc);
	break;
    case MRT_ASSERT:
	error = sooptcopyin(sopt, &optval, sizeof optval, sizeof optval);
	if (error)
	    break;
	set_assert(optval);
	break;
    case MRT_API_CONFIG:
	error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
	if (!error)
	    error = set_api_config(&i);
	if (!error)
	    error = sooptcopyout(sopt, &i, sizeof i);
	break;
    case MRT_ADD_BW_UPCALL:
    case MRT_DEL_BW_UPCALL:
	error = sooptcopyin(sopt, &bw_upcall, sizeof bw_upcall,
				sizeof bw_upcall);
	if (error)
	    break;
	if (sopt->sopt_name == MRT_ADD_BW_UPCALL)
	    error = add_bw_upcall(&bw_upcall);
	else
	    error = del_bw_upcall(&bw_upcall);
	break;
    default:
	error = EOPNOTSUPP;
	break;
    }
    return error;
}
static int X_ip_mrouter_set ( struct socket * so , struct sockopt * sopt ) { int error , optval ; vifi_t vifi ; struct vifctl vifc ; struct mfcctl2 mfc ; struct bw_upcall bw_upcall ; uint32_t i ; if ( so != V_ip_mrouter && sopt -> sopt_name != MRT_INIT ) return EPERM ; error = 0 ; switch ( sopt -> sopt_name ) { case MRT_INIT : error = sooptcopyin ( sopt , & optval , sizeof optval , sizeof optval ) ; if ( error ) break ; error = ip_mrouter_init ( so , optval ) ; break ; case MRT_DONE : error = ip_mrouter_done ( ) ; break ; case MRT_ADD_VIF : error = sooptcopyin ( sopt , & vifc , sizeof vifc , sizeof vifc ) ; if ( error ) break ; error = add_vif ( & vifc ) ; break ; case MRT_DEL_VIF : error = sooptcopyin ( sopt , & vifi , sizeof vifi , sizeof vifi ) ; if ( error ) break ; error = del_vif ( vifi ) ; break ; case MRT_ADD_MFC : case MRT_DEL_MFC : if ( sopt -> sopt_name == MRT_ADD_MFC && V_mrt_api_config & MRT_API_FLAGS_ALL ) { error = sooptcopyin ( sopt , & mfc , sizeof ( struct mfcctl2 ) , sizeof ( struct mfcctl2 ) ) ; } else { error = sooptcopyin ( sopt , & mfc , sizeof ( struct mfcctl ) , sizeof ( struct mfcctl ) ) ; bzero ( ( caddr_t ) & mfc + sizeof ( struct mfcctl ) , sizeof ( mfc ) - sizeof ( struct mfcctl ) ) ; } if ( error ) break ; if ( sopt -> sopt_name == MRT_ADD_MFC ) error = add_mfc ( & mfc ) ; else error = del_mfc ( & mfc ) ; break ; case MRT_ASSERT : error = sooptcopyin ( sopt , & optval , sizeof optval , sizeof optval ) ; if ( error ) break ; set_assert ( optval ) ; break ; case MRT_API_CONFIG : error = sooptcopyin ( sopt , & i , sizeof i , sizeof i ) ; if ( ! error ) error = set_api_config ( & i ) ; if ( ! error ) error = sooptcopyout ( sopt , & i , sizeof i ) ; break ; case MRT_ADD_BW_UPCALL : case MRT_DEL_BW_UPCALL : error = sooptcopyin ( sopt , & bw_upcall , sizeof bw_upcall , sizeof bw_upcall ) ; if ( error ) break ; if ( sopt -> sopt_name == MRT_ADD_BW_UPCALL ) error = add_bw_upcall ( & bw_upcall ) ; else error = del_bw_upcall ( & bw_upcall ) ; break ; default : error = EOPNOTSUPP ; break ; } return error ; }
Handle MRT setsockopt commands to modify the multicast forwarding tables.
Handle MRT setsockopt commands to modify the multicast forwarding tables .
/*
	 * select data size depending on API version.
	 */