+
+int cp_pipe_from_user_32( struct sockopt *sopt, struct dn_pipe *p )
+{
+ struct dn_pipe_32 user_pipe_32;
+ int error=0;
+
+ error = sooptcopyin(sopt, &user_pipe_32, sizeof(struct dn_pipe_32), sizeof(struct dn_pipe_32));
+ if ( !error ){
+ p->pipe_nr = user_pipe_32.pipe_nr;
+ p->bandwidth = user_pipe_32.bandwidth;
+ p->delay = user_pipe_32.delay;
+ p->V = user_pipe_32.V;
+ p->sum = user_pipe_32.sum;
+ p->numbytes = user_pipe_32.numbytes;
+ p->sched_time = user_pipe_32.sched_time;
+ bcopy( user_pipe_32.if_name, p->if_name, IFNAMSIZ);
+ p->ready = user_pipe_32.ready;
+
+ p->fs.fs_nr = user_pipe_32.fs.fs_nr;
+ p->fs.flags_fs = user_pipe_32.fs.flags_fs;
+ p->fs.parent_nr = user_pipe_32.fs.parent_nr;
+ p->fs.weight = user_pipe_32.fs.weight;
+ p->fs.qsize = user_pipe_32.fs.qsize;
+ p->fs.plr = user_pipe_32.fs.plr;
+ p->fs.flow_mask = user_pipe_32.fs.flow_mask;
+ p->fs.rq_size = user_pipe_32.fs.rq_size;
+ p->fs.rq_elements = user_pipe_32.fs.rq_elements;
+ p->fs.last_expired = user_pipe_32.fs.last_expired;
+ p->fs.backlogged = user_pipe_32.fs.backlogged;
+ p->fs.w_q = user_pipe_32.fs.w_q;
+ p->fs.max_th = user_pipe_32.fs.max_th;
+ p->fs.min_th = user_pipe_32.fs.min_th;
+ p->fs.max_p = user_pipe_32.fs.max_p;
+ p->fs.c_1 = user_pipe_32.fs.c_1;
+ p->fs.c_2 = user_pipe_32.fs.c_2;
+ p->fs.c_3 = user_pipe_32.fs.c_3;
+ p->fs.c_4 = user_pipe_32.fs.c_4;
+ p->fs.lookup_depth = user_pipe_32.fs.lookup_depth;
+ p->fs.lookup_step = user_pipe_32.fs.lookup_step;
+ p->fs.lookup_weight = user_pipe_32.fs.lookup_weight;
+ p->fs.avg_pkt_size = user_pipe_32.fs.avg_pkt_size;
+ p->fs.max_pkt_size = user_pipe_32.fs.max_pkt_size;
+ }
+ return error;
+}
+
+
+int cp_pipe_from_user_64( struct sockopt *sopt, struct dn_pipe *p )
+{
+ struct dn_pipe_64 user_pipe_64;
+ int error=0;
+
+ error = sooptcopyin(sopt, &user_pipe_64, sizeof(struct dn_pipe_64), sizeof(struct dn_pipe_64));
+ if ( !error ){
+ p->pipe_nr = user_pipe_64.pipe_nr;
+ p->bandwidth = user_pipe_64.bandwidth;
+ p->delay = user_pipe_64.delay;
+ p->V = user_pipe_64.V;
+ p->sum = user_pipe_64.sum;
+ p->numbytes = user_pipe_64.numbytes;
+ p->sched_time = user_pipe_64.sched_time;
+ bcopy( user_pipe_64.if_name, p->if_name, IFNAMSIZ);
+ p->ready = user_pipe_64.ready;
+
+ p->fs.fs_nr = user_pipe_64.fs.fs_nr;
+ p->fs.flags_fs = user_pipe_64.fs.flags_fs;
+ p->fs.parent_nr = user_pipe_64.fs.parent_nr;
+ p->fs.weight = user_pipe_64.fs.weight;
+ p->fs.qsize = user_pipe_64.fs.qsize;
+ p->fs.plr = user_pipe_64.fs.plr;
+ p->fs.flow_mask = user_pipe_64.fs.flow_mask;
+ p->fs.rq_size = user_pipe_64.fs.rq_size;
+ p->fs.rq_elements = user_pipe_64.fs.rq_elements;
+ p->fs.last_expired = user_pipe_64.fs.last_expired;
+ p->fs.backlogged = user_pipe_64.fs.backlogged;
+ p->fs.w_q = user_pipe_64.fs.w_q;
+ p->fs.max_th = user_pipe_64.fs.max_th;
+ p->fs.min_th = user_pipe_64.fs.min_th;
+ p->fs.max_p = user_pipe_64.fs.max_p;
+ p->fs.c_1 = user_pipe_64.fs.c_1;
+ p->fs.c_2 = user_pipe_64.fs.c_2;
+ p->fs.c_3 = user_pipe_64.fs.c_3;
+ p->fs.c_4 = user_pipe_64.fs.c_4;
+ p->fs.lookup_depth = user_pipe_64.fs.lookup_depth;
+ p->fs.lookup_step = user_pipe_64.fs.lookup_step;
+ p->fs.lookup_weight = user_pipe_64.fs.lookup_weight;
+ p->fs.avg_pkt_size = user_pipe_64.fs.avg_pkt_size;
+ p->fs.max_pkt_size = user_pipe_64.fs.max_pkt_size;
+ }
+ return error;
+}
+
+static void
+cp_flow_set_to_32_user(struct dn_flow_set *set, struct dn_flow_set_32 *fs_bp)
+{
+ fs_bp->fs_nr = set->fs_nr;
+ fs_bp->flags_fs = set->flags_fs ;
+ fs_bp->parent_nr = set->parent_nr ;
+ fs_bp->weight = set->weight ;
+ fs_bp->qsize = set->qsize ;
+ fs_bp->plr = set->plr ;
+ fs_bp->flow_mask = set->flow_mask ;
+ fs_bp->rq_size = set->rq_size ;
+ fs_bp->rq_elements = set->rq_elements ;
+ fs_bp->last_expired = set->last_expired ;
+ fs_bp->backlogged = set->backlogged ;
+ fs_bp->w_q = set->w_q ;
+ fs_bp->max_th = set->max_th ;
+ fs_bp->min_th = set->min_th ;
+ fs_bp->max_p = set->max_p ;
+ fs_bp->c_1 = set->c_1 ;
+ fs_bp->c_2 = set->c_2 ;
+ fs_bp->c_3 = set->c_3 ;
+ fs_bp->c_4 = set->c_4 ;
+ fs_bp->w_q_lookup = CAST_DOWN_EXPLICIT(user32_addr_t, set->w_q_lookup) ;
+ fs_bp->lookup_depth = set->lookup_depth ;
+ fs_bp->lookup_step = set->lookup_step ;
+ fs_bp->lookup_weight = set->lookup_weight ;
+ fs_bp->avg_pkt_size = set->avg_pkt_size ;
+ fs_bp->max_pkt_size = set->max_pkt_size ;
+}
+
+static void
+cp_flow_set_to_64_user(struct dn_flow_set *set, struct dn_flow_set_64 *fs_bp)
+{
+ fs_bp->fs_nr = set->fs_nr;
+ fs_bp->flags_fs = set->flags_fs ;
+ fs_bp->parent_nr = set->parent_nr ;
+ fs_bp->weight = set->weight ;
+ fs_bp->qsize = set->qsize ;
+ fs_bp->plr = set->plr ;
+ fs_bp->flow_mask = set->flow_mask ;
+ fs_bp->rq_size = set->rq_size ;
+ fs_bp->rq_elements = set->rq_elements ;
+ fs_bp->last_expired = set->last_expired ;
+ fs_bp->backlogged = set->backlogged ;
+ fs_bp->w_q = set->w_q ;
+ fs_bp->max_th = set->max_th ;
+ fs_bp->min_th = set->min_th ;
+ fs_bp->max_p = set->max_p ;
+ fs_bp->c_1 = set->c_1 ;
+ fs_bp->c_2 = set->c_2 ;
+ fs_bp->c_3 = set->c_3 ;
+ fs_bp->c_4 = set->c_4 ;
+ fs_bp->w_q_lookup = CAST_DOWN(user64_addr_t, set->w_q_lookup) ;
+ fs_bp->lookup_depth = set->lookup_depth ;
+ fs_bp->lookup_step = set->lookup_step ;
+ fs_bp->lookup_weight = set->lookup_weight ;
+ fs_bp->avg_pkt_size = set->avg_pkt_size ;
+ fs_bp->max_pkt_size = set->max_pkt_size ;
+}
+
+static
+void cp_queue_to_32_user( struct dn_flow_queue *q, struct dn_flow_queue_32 *qp)
+{
+ qp->id = q->id;
+ qp->len = q->len;
+ qp->len_bytes = q->len_bytes;
+ qp->numbytes = q->numbytes;
+ qp->tot_pkts = q->tot_pkts;
+ qp->tot_bytes = q->tot_bytes;
+ qp->drops = q->drops;
+ qp->hash_slot = q->hash_slot;
+ qp->avg = q->avg;
+ qp->count = q->count;
+ qp->random = q->random;
+ qp->q_time = q->q_time;
+ qp->heap_pos = q->heap_pos;
+ qp->sched_time = q->sched_time;
+ qp->S = q->S;
+ qp->F = q->F;
+}
+
+static
+void cp_queue_to_64_user( struct dn_flow_queue *q, struct dn_flow_queue_64 *qp)
+{
+ qp->id = q->id;
+ qp->len = q->len;
+ qp->len_bytes = q->len_bytes;
+ qp->numbytes = q->numbytes;
+ qp->tot_pkts = q->tot_pkts;
+ qp->tot_bytes = q->tot_bytes;
+ qp->drops = q->drops;
+ qp->hash_slot = q->hash_slot;
+ qp->avg = q->avg;
+ qp->count = q->count;
+ qp->random = q->random;
+ qp->q_time = q->q_time;
+ qp->heap_pos = q->heap_pos;
+ qp->sched_time = q->sched_time;
+ qp->S = q->S;
+ qp->F = q->F;
+}
+
+static
+char *cp_pipe_to_32_user(struct dn_pipe *p, struct dn_pipe_32 *pipe_bp)
+{
+ char *bp;
+
+ pipe_bp->pipe_nr = p->pipe_nr;
+ pipe_bp->bandwidth = p->bandwidth;
+ pipe_bp->delay = p->delay;
+ bcopy( &(p->scheduler_heap), &(pipe_bp->scheduler_heap), sizeof(struct dn_heap_32));
+ pipe_bp->scheduler_heap.p = CAST_DOWN_EXPLICIT(user32_addr_t, pipe_bp->scheduler_heap.p);
+ bcopy( &(p->not_eligible_heap), &(pipe_bp->not_eligible_heap), sizeof(struct dn_heap_32));
+ pipe_bp->not_eligible_heap.p = CAST_DOWN_EXPLICIT(user32_addr_t, pipe_bp->not_eligible_heap.p);
+ bcopy( &(p->idle_heap), &(pipe_bp->idle_heap), sizeof(struct dn_heap_32));
+ pipe_bp->idle_heap.p = CAST_DOWN_EXPLICIT(user32_addr_t, pipe_bp->idle_heap.p);
+ pipe_bp->V = p->V;
+ pipe_bp->sum = p->sum;
+ pipe_bp->numbytes = p->numbytes;
+ pipe_bp->sched_time = p->sched_time;
+ bcopy( p->if_name, pipe_bp->if_name, IFNAMSIZ);
+ pipe_bp->ifp = CAST_DOWN_EXPLICIT(user32_addr_t, p->ifp);
+ pipe_bp->ready = p->ready;
+
+ cp_flow_set_to_32_user( &(p->fs), &(pipe_bp->fs));
+
+ pipe_bp->delay = (pipe_bp->delay * 1000) / (hz*10) ;
+ /*
+ * XXX the following is a hack based on ->next being the
+ * first field in dn_pipe and dn_flow_set. The correct
+ * solution would be to move the dn_flow_set to the beginning
+ * of struct dn_pipe.
+ */
+ pipe_bp->next = CAST_DOWN_EXPLICIT( user32_addr_t, DN_IS_PIPE );
+ /* clean pointers */
+ pipe_bp->head = pipe_bp->tail = (user32_addr_t) 0 ;
+ pipe_bp->fs.next = (user32_addr_t)0 ;
+ pipe_bp->fs.pipe = (user32_addr_t)0 ;
+ pipe_bp->fs.rq = (user32_addr_t)0 ;
+ bp = ((char *)pipe_bp) + sizeof(struct dn_pipe_32);
+ return( dn_copy_set_32( &(p->fs), bp) );
+}
+
+static
+char *cp_pipe_to_64_user(struct dn_pipe *p, struct dn_pipe_64 *pipe_bp)
+{
+ char *bp;
+
+ pipe_bp->pipe_nr = p->pipe_nr;
+ pipe_bp->bandwidth = p->bandwidth;
+ pipe_bp->delay = p->delay;
+ bcopy( &(p->scheduler_heap), &(pipe_bp->scheduler_heap), sizeof(struct dn_heap_64));
+ pipe_bp->scheduler_heap.p = CAST_DOWN(user64_addr_t, pipe_bp->scheduler_heap.p);
+ bcopy( &(p->not_eligible_heap), &(pipe_bp->not_eligible_heap), sizeof(struct dn_heap_64));
+ pipe_bp->not_eligible_heap.p = CAST_DOWN(user64_addr_t, pipe_bp->not_eligible_heap.p);
+ bcopy( &(p->idle_heap), &(pipe_bp->idle_heap), sizeof(struct dn_heap_64));
+ pipe_bp->idle_heap.p = CAST_DOWN(user64_addr_t, pipe_bp->idle_heap.p);
+ pipe_bp->V = p->V;
+ pipe_bp->sum = p->sum;
+ pipe_bp->numbytes = p->numbytes;
+ pipe_bp->sched_time = p->sched_time;
+ bcopy( p->if_name, pipe_bp->if_name, IFNAMSIZ);
+ pipe_bp->ifp = CAST_DOWN(user64_addr_t, p->ifp);
+ pipe_bp->ready = p->ready;
+
+ cp_flow_set_to_64_user( &(p->fs), &(pipe_bp->fs));
+
+ pipe_bp->delay = (pipe_bp->delay * 1000) / (hz*10) ;
+ /*
+ * XXX the following is a hack based on ->next being the
+ * first field in dn_pipe and dn_flow_set. The correct
+ * solution would be to move the dn_flow_set to the beginning
+ * of struct dn_pipe.
+ */
+ pipe_bp->next = CAST_DOWN( user64_addr_t, DN_IS_PIPE );
+ /* clean pointers */
+ pipe_bp->head = pipe_bp->tail = USER_ADDR_NULL ;
+ pipe_bp->fs.next = USER_ADDR_NULL ;
+ pipe_bp->fs.pipe = USER_ADDR_NULL ;
+ pipe_bp->fs.rq = USER_ADDR_NULL ;
+ bp = ((char *)pipe_bp) + sizeof(struct dn_pipe_64);
+ return( dn_copy_set_64( &(p->fs), bp) );
+}
+