4 Copyright 1995 Philip Homburg
26 FORWARD
void ip_close
ARGS(( int fd
));
27 FORWARD
int ip_cancel
ARGS(( int fd
, int which_operation
));
28 FORWARD
int ip_select
ARGS(( int fd
, unsigned operations
));
30 FORWARD
void ip_buffree
ARGS(( int priority
));
31 #ifdef BUF_CONSISTENCY_CHECK
32 FORWARD
void ip_bufcheck
ARGS(( void ));
34 FORWARD
void ip_bad_callback
ARGS(( struct ip_port
*ip_port
));
36 PUBLIC ip_port_t
*ip_port_table
;
37 PUBLIC ip_fd_t ip_fd_table
[IP_FD_NR
];
38 PUBLIC ip_ass_t ip_ass_table
[IP_ASS_NR
];
42 ip_port_table
= alloc(ip_conf_nr
* sizeof(ip_port_table
[0]));
54 assert (BUF_S
>= sizeof(struct nwio_ethopt
));
55 assert (BUF_S
>= IP_MAX_HDR_SIZE
+ ETH_HDR_SIZE
);
56 assert (BUF_S
>= sizeof(nwio_ipopt_t
));
57 assert (BUF_S
>= sizeof(nwio_route_t
));
59 for (i
=0, ip_ass
= ip_ass_table
; i
<IP_ASS_NR
; i
++, ip_ass
++)
62 ip_ass
->ia_first_time
= 0;
66 for (i
=0, ip_fd
= ip_fd_table
; i
<IP_FD_NR
; i
++, ip_fd
++)
68 ip_fd
->if_flags
= IFF_EMPTY
;
69 ip_fd
->if_rdbuf_head
= 0;
72 for (i
=0, ip_port
= ip_port_table
, icp
= ip_conf
;
73 i
<ip_conf_nr
; i
++, ip_port
++, icp
++)
76 ip_port
->ip_flags
= IPF_EMPTY
;
77 ip_port
->ip_dev_main
= (ip_dev_t
)ip_bad_callback
;
78 ip_port
->ip_dev_set_ipaddr
= (ip_dev_t
)ip_bad_callback
;
79 ip_port
->ip_dev_send
= (ip_dev_send_t
)ip_bad_callback
;
80 ip_port
->ip_dl_type
= icp
->ic_devtype
;
81 ip_port
->ip_mtu
= IP_DEF_MTU
;
82 ip_port
->ip_mtu_max
= IP_MAX_PACKSIZE
;
84 switch(ip_port
->ip_dl_type
)
87 ip_port
->ip_dl
.dl_eth
.de_port
= icp
->ic_port
;
88 result
= ipeth_init(ip_port
);
91 assert(result
== NW_OK
);
94 ip_port
->ip_dl
.dl_ps
.ps_port
= icp
->ic_port
;
95 result
= ipps_init(ip_port
);
98 assert(result
== NW_OK
);
101 ip_panic(( "unknown ip_dl_type %d",
102 ip_port
->ip_dl_type
));
105 ip_port
->ip_loopb_head
= NULL
;
106 ip_port
->ip_loopb_tail
= NULL
;
107 ev_init(&ip_port
->ip_loopb_event
);
108 ip_port
->ip_routeq_head
= NULL
;
109 ip_port
->ip_routeq_tail
= NULL
;
110 ev_init(&ip_port
->ip_routeq_event
);
111 ip_port
->ip_flags
|= IPF_CONFIGURED
;
112 ip_port
->ip_proto_any
= NULL
;
113 for (j
= 0; j
<IP_PROTO_HASH_NR
; j
++)
114 ip_port
->ip_proto
[j
]= NULL
;
117 #ifndef BUF_CONSISTENCY_CHECK
118 bf_logon(ip_buffree
);
120 bf_logon(ip_buffree
, ip_bufcheck
);
126 for (i
=0, ip_port
= ip_port_table
; i
<ip_conf_nr
; i
++, ip_port
++)
128 if (!(ip_port
->ip_flags
& IPF_CONFIGURED
))
130 ip_port
->ip_frame_id
= (u16_t
)get_time();
132 sr_add_minor(if2minor(ip_conf
[i
].ic_ifno
, IP_DEV_OFF
),
133 i
, ip_open
, ip_close
, ip_read
,
134 ip_write
, ip_ioctl
, ip_cancel
, ip_select
);
136 (*ip_port
->ip_dev_main
)(ip_port
);
140 PRIVATE
int ip_cancel (fd
, which_operation
)
148 ip_fd
= &ip_fd_table
[fd
];
150 switch (which_operation
)
152 case SR_CANCEL_IOCTL
:
153 assert (ip_fd
->if_flags
& IFF_IOCTL_IP
);
154 ip_fd
->if_flags
&= ~IFF_IOCTL_IP
;
155 repl_res
= (*ip_fd
->if_get_userdata
)(ip_fd
->if_srfd
,
156 (size_t)EINTR
, (size_t)0, TRUE
);
160 assert (ip_fd
->if_flags
& IFF_READ_IP
);
161 ip_fd
->if_flags
&= ~IFF_READ_IP
;
162 result
= (*ip_fd
->if_put_userdata
)(ip_fd
->if_srfd
,
163 (size_t)EINTR
, (acc_t
*)0, FALSE
);
167 case SR_CANCEL_WRITE
:
169 assert (ip_fd
->if_flags
& IFF_WRITE_MASK
);
170 ip_fd
->if_flags
&= ~IFF_WRITE_MASK
;
171 repl_res
= (*ip_fd
->if_get_userdata
)(ip_fd
->if_srfd
,
172 (size_t)EINTR
, (size_t)0, FALSE
);
177 ip_panic(( "unknown cancel request" ));
183 PRIVATE
int ip_select(fd
, operations
)
187 printf("ip_select: not implemented\n");
191 PUBLIC
int ip_open (port
, srfd
, get_userdata
, put_userdata
, put_pkt
,
195 get_userdata_t get_userdata
;
196 put_userdata_t put_userdata
;
198 select_res_t select_res
;
204 ip_port
= &ip_port_table
[port
];
205 if (!(ip_port
->ip_flags
& IPF_CONFIGURED
))
208 for (i
=0; i
<IP_FD_NR
&& (ip_fd_table
[i
].if_flags
& IFF_INUSE
);
213 DBLOCK(1, printf("out of fds\n"));
217 ip_fd
= &ip_fd_table
[i
];
219 ip_fd
->if_flags
= IFF_INUSE
;
221 ip_fd
->if_ipopt
.nwio_flags
= NWIO_DEFAULT
;
222 ip_fd
->if_ipopt
.nwio_tos
= 0;
223 ip_fd
->if_ipopt
.nwio_df
= FALSE
;
224 ip_fd
->if_ipopt
.nwio_ttl
= 255;
225 ip_fd
->if_ipopt
.nwio_hdropt
.iho_opt_siz
= 0;
227 ip_fd
->if_port
= ip_port
;
228 ip_fd
->if_srfd
= srfd
;
229 assert(ip_fd
->if_rdbuf_head
== NULL
);
230 ip_fd
->if_get_userdata
= get_userdata
;
231 ip_fd
->if_put_userdata
= put_userdata
;
232 ip_fd
->if_put_pkt
= put_pkt
;
237 PRIVATE
void ip_close (fd
)
243 ip_fd
= &ip_fd_table
[fd
];
245 assert ((ip_fd
->if_flags
& IFF_INUSE
) &&
246 !(ip_fd
->if_flags
& IFF_BUSY
));
248 if (ip_fd
->if_flags
& IFF_OPTSET
)
249 ip_unhash_proto(ip_fd
);
250 while (ip_fd
->if_rdbuf_head
)
252 pack
= ip_fd
->if_rdbuf_head
;
253 ip_fd
->if_rdbuf_head
= pack
->acc_ext_link
;
256 ip_fd
->if_flags
= IFF_EMPTY
;
259 PRIVATE
void ip_buffree(priority
)
266 acc_t
*pack
, *next_pack
;
268 for (i
= 0, ip_port
= ip_port_table
; i
<ip_conf_nr
; i
++, ip_port
++)
270 if (ip_port
->ip_dl_type
== IPDL_ETH
)
272 /* Can't free de_frame.
273 * bf_check_acc(ip_port->ip_dl.dl_eth.de_frame);
275 if (priority
== IP_PRI_PORTBUFS
)
277 next_pack
= ip_port
->ip_dl
.dl_eth
.de_arp_head
;
278 while(next_pack
!= NULL
)
281 next_pack
= pack
->acc_ext_link
;
284 ip_port
->ip_dl
.dl_eth
.de_arp_head
= next_pack
;
286 next_pack
= ip_port
->ip_dl
.dl_eth
.de_q_head
;
287 while(next_pack
!= NULL
)
290 next_pack
= pack
->acc_ext_link
;
293 ip_port
->ip_dl
.dl_eth
.de_q_head
= next_pack
;
296 else if (ip_port
->ip_dl_type
== IPDL_PSIP
)
298 if (priority
== IP_PRI_PORTBUFS
)
300 next_pack
= ip_port
->ip_dl
.dl_ps
.ps_send_head
;
301 while (next_pack
!= NULL
)
304 next_pack
= pack
->acc_ext_link
;
307 ip_port
->ip_dl
.dl_ps
.ps_send_head
= next_pack
;
310 if (priority
== IP_PRI_PORTBUFS
)
312 next_pack
= ip_port
->ip_loopb_head
;
313 while(next_pack
&& next_pack
->acc_ext_link
)
316 next_pack
= pack
->acc_ext_link
;
321 if (ev_in_queue(&ip_port
->ip_loopb_event
))
325 "not freeing ip_loopb_head, ip_loopb_event enqueued\n");
334 ip_port
->ip_loopb_head
= next_pack
;
336 next_pack
= ip_port
->ip_routeq_head
;
337 while(next_pack
&& next_pack
->acc_ext_link
)
340 next_pack
= pack
->acc_ext_link
;
345 if (ev_in_queue(&ip_port
->ip_routeq_event
))
349 "not freeing ip_loopb_head, ip_routeq_event enqueued\n");
358 ip_port
->ip_routeq_head
= next_pack
;
361 if (priority
== IP_PRI_FDBUFS_EXTRA
)
363 for (i
= 0, ip_fd
= ip_fd_table
; i
<IP_FD_NR
; i
++, ip_fd
++)
365 while (ip_fd
->if_rdbuf_head
&&
366 ip_fd
->if_rdbuf_head
->acc_ext_link
)
368 pack
= ip_fd
->if_rdbuf_head
;
369 ip_fd
->if_rdbuf_head
= pack
->acc_ext_link
;
374 if (priority
== IP_PRI_FDBUFS
)
376 for (i
= 0, ip_fd
= ip_fd_table
; i
<IP_FD_NR
; i
++, ip_fd
++)
378 while (ip_fd
->if_rdbuf_head
)
380 pack
= ip_fd
->if_rdbuf_head
;
381 ip_fd
->if_rdbuf_head
= pack
->acc_ext_link
;
386 if (priority
== IP_PRI_ASSBUFS
)
388 for (i
= 0, ip_ass
= ip_ass_table
; i
<IP_ASS_NR
; i
++, ip_ass
++)
390 next_pack
= ip_ass
->ia_frags
;
391 while(ip_ass
->ia_frags
!= NULL
)
393 pack
= ip_ass
->ia_frags
;
394 ip_ass
->ia_frags
= pack
->acc_ext_link
;
397 ip_ass
->ia_first_time
= 0;
402 #ifdef BUF_CONSISTENCY_CHECK
403 PRIVATE
void ip_bufcheck()
411 for (i
= 0, ip_port
= ip_port_table
; i
<ip_conf_nr
; i
++, ip_port
++)
413 if (ip_port
->ip_dl_type
== IPDL_ETH
)
415 bf_check_acc(ip_port
->ip_dl
.dl_eth
.de_frame
);
416 for (pack
= ip_port
->ip_dl
.dl_eth
.de_q_head
; pack
;
417 pack
= pack
->acc_ext_link
)
421 for (pack
= ip_port
->ip_dl
.dl_eth
.de_arp_head
; pack
;
422 pack
= pack
->acc_ext_link
)
427 else if (ip_port
->ip_dl_type
== IPDL_PSIP
)
429 for (pack
= ip_port
->ip_dl
.dl_ps
.ps_send_head
; pack
;
430 pack
= pack
->acc_ext_link
)
435 for (pack
= ip_port
->ip_loopb_head
; pack
;
436 pack
= pack
->acc_ext_link
)
440 for (pack
= ip_port
->ip_routeq_head
; pack
;
441 pack
= pack
->acc_ext_link
)
446 for (i
= 0, ip_fd
= ip_fd_table
; i
<IP_FD_NR
; i
++, ip_fd
++)
448 for (pack
= ip_fd
->if_rdbuf_head
; pack
;
449 pack
= pack
->acc_ext_link
)
454 for (i
= 0, ip_ass
= ip_ass_table
; i
<IP_ASS_NR
; i
++, ip_ass
++)
456 for (pack
= ip_ass
->ia_frags
; pack
; pack
= pack
->acc_ext_link
)
460 #endif /* BUF_CONSISTENCY_CHECK */
462 PRIVATE
void ip_bad_callback(ip_port
)
463 struct ip_port
*ip_port
;
465 ip_panic(( "no callback filled in for port %d", ip_port
->ip_port
));
469 * $PchId: ip.c,v 1.19 2005/06/28 14:17:40 philip Exp $