]> Zhao Yanbai Git Server - minix.git/commitdiff
Do not abort/panic when an ethernet driver does something unexpected.
authorPhilip Homburg <philip@cs.vu.nl>
Mon, 28 Aug 2006 12:59:36 +0000 (12:59 +0000)
committerPhilip Homburg <philip@cs.vu.nl>
Mon, 28 Aug 2006 12:59:36 +0000 (12:59 +0000)
servers/inet/inet.c
servers/inet/mnx_eth.c
servers/inet/osdep_eth.h

index f866dadc08133ab43e13f310be72e0c875df7f3d..9ce7db78c8e6e1b05411b839beb74f094bced015 100644 (file)
@@ -258,12 +258,17 @@ PUBLIC void main()
                        mq_free(mq);
                }
 #endif
-               else
+               else if (mq->mq_mess.m_type == DL_TASK_REPLY)
                {
-compare(mq->mq_mess.m_type, ==, DL_TASK_REPLY);
                        eth_rec(&mq->mq_mess);
                        mq_free(mq);
                }
+               else
+               {
+                       printf("inet: got bad message type 0x%x from %d\n",
+                               mq->mq_mess.m_type, mq->mq_mess.m_source);
+                       mq_free(mq);
+               }
        }
        ip_panic(("task is not allowed to terminate"));
 }
index dad9d60b7a89bb30f662843576e651775d41481f..44bb82e3fca61d80cb2cc3e05fe1b1ab9ea33e01 100644 (file)
@@ -108,6 +108,7 @@ PUBLIC void osdep_eth_init()
 
                eth_port->etp_osdep.etp_port= ecp->ec_port;
                eth_port->etp_osdep.etp_task= tasknr;
+               eth_port->etp_osdep.etp_send_ev= 0;
                ev_init(&eth_port->etp_osdep.etp_recvev);
 
                mess.m_type= DL_CONF;
@@ -335,6 +336,8 @@ acc_t *pack;
                        assert(loc_port != eth_port);
                        loc_port->etp_osdep.etp_sendrepl= block_msg;
                        ev_arg.ev_ptr= loc_port;
+                       assert(!loc_port->etp_osdep.etp_send_ev);
+                       loc_port->etp_osdep.etp_send_ev= 1;
                        ev_enqueue(&loc_port->etp_sendev, eth_sendev, ev_arg);
                }
                if (block_msg.DL_STAT & DL_PACK_RECV)
@@ -359,6 +362,17 @@ acc_t *pack;
                return;
        }
 
+       if (mess1.m_type != DL_TASK_REPLY ||
+               mess1.DL_PORT != eth_port->etp_osdep.etp_port ||
+               mess1.DL_PROC != this_proc)
+       {
+               printf(
+"eth_write_port: ignoring bad message (type = 0x%x, port = %d, proc = %d) from %d\n",
+                       mess1.m_type, mess1.DL_PORT, mess1.DL_PROC,
+                       mess1.m_source);
+               return;
+       }
+
        assert(mess1.m_type == DL_TASK_REPLY &&
                mess1.DL_PORT == eth_port->etp_osdep.etp_port &&
                mess1.DL_PROC == this_proc);
@@ -392,6 +406,8 @@ acc_t *pack;
        {
                eth_port->etp_osdep.etp_sendrepl= mess1;
                ev_arg.ev_ptr= eth_port;
+               assert(!eth_port->etp_osdep.etp_send_ev);
+               eth_port->etp_osdep.etp_send_ev= 1;
                ev_enqueue(&eth_port->etp_sendev, eth_sendev, ev_arg);
 
                /* Pretend that we didn't get a reply. */
@@ -428,7 +444,8 @@ message *m;
 
        stat= m->DL_STAT & 0xffff;
 
-       assert(stat & (DL_PACK_SEND|DL_PACK_RECV));
+       if (!(stat & (DL_PACK_SEND|DL_PACK_RECV)))
+               printf("eth_rec: neither DL_PACK_SEND nor DL_PACK_RECV\n");
        if (stat & DL_PACK_SEND)
                write_int(loc_port);
        if (stat & DL_PACK_RECV)
@@ -615,6 +632,14 @@ eth_port_t *eth_port;
        u8_t *eth_dst_ptr;
 
        pack= eth_port->etp_wr_pack;
+       if (pack == NULL)
+       {
+               printf("write_int: strange no packet on eth port %d\n",
+                       eth_port-eth_port_table);
+               eth_restart_write(eth_port);
+               return;
+       }
+
        eth_port->etp_wr_pack= NULL;
 
        eth_dst_ptr= (u8_t *)ptr2acc_data(pack);
@@ -642,14 +667,29 @@ int count;
        pack= eth_port->etp_rd_pack;
        eth_port->etp_rd_pack= NULL;
 
-       cut_pack= bf_cut(pack, 0, count);
-       bf_afree(pack);
+       if (count < ETH_MIN_PACK_SIZE)
+       {
+               printf("mnx_eth`read_int: packet size too small (%d)\n",
+                       count);
+               bf_afree(pack);
+       }
+       else if (count > ETH_MAX_PACK_SIZE_TAGGED)
+       {
+               printf("mnx_eth`read_int: packet size too big (%d)\n",
+                       count);
+               bf_afree(pack);
+       }
+       else
+       {
+               cut_pack= bf_cut(pack, 0, count);
+               bf_afree(pack);
 
-       assert(!no_ethWritePort);
-       no_ethWritePort= 1;
-       eth_arrive(eth_port, cut_pack, count);
-       assert(no_ethWritePort);
-       no_ethWritePort= 0;
+               assert(!no_ethWritePort);
+               no_ethWritePort= 1;
+               eth_arrive(eth_port, cut_pack, count);
+               assert(no_ethWritePort);
+               no_ethWritePort= 0;
+       }
        
        eth_port->etp_flags &= ~(EPF_READ_IP|EPF_READ_SP);
        setup_read(eth_port);
@@ -738,10 +778,13 @@ eth_port_t *eth_port;
                                (DL_PACK_SEND|DL_PACK_RECV));
                        if (block_msg.DL_STAT & DL_PACK_SEND)
                        {
-                               loc_port->etp_osdep.etp_sendrepl= block_msg;
+                               loc_port->etp_osdep.etp_sendrepl=
+                                       block_msg;
                                ev_arg.ev_ptr= loc_port;
-                               ev_enqueue(&loc_port->etp_sendev, eth_sendev,
-                                       ev_arg);
+                               assert(!loc_port->etp_osdep.etp_send_ev);
+                               loc_port->etp_osdep.etp_send_ev= 1;
+                               ev_enqueue(&loc_port->etp_sendev,
+                                       eth_sendev, ev_arg);
                        }
                        if (block_msg.DL_STAT & DL_PACK_RECV)
                        {
@@ -768,10 +811,23 @@ eth_port_t *eth_port;
                        continue;
                }
 
-               assert (mess1.m_type == DL_TASK_REPLY &&
-                       mess1.DL_PORT == mess1.DL_PORT &&
-                       mess1.DL_PROC == this_proc);
-               compare((mess1.DL_STAT >> 16), ==, OK);
+               if (mess1.m_type != DL_TASK_REPLY ||
+                       mess1.DL_PORT !=  eth_port->etp_osdep.etp_port ||
+                       mess1.DL_PROC != this_proc)
+               {
+                       printf("mnx_eth`setup_read: bad type, port or proc\n");
+                       printf("got type %d, port %d, proc %d\n",
+                               mess1.m_type, mess1.DL_PORT, mess1.DL_PROC);
+                       continue;
+               }
+
+               if ((mess1.DL_STAT >> 16) != OK)
+               {
+                       printf(
+                       "mnx_eth`setup_read: bad value in DL_STAT: 0x%x\n",
+                               mess1.DL_STAT);
+                       mess1.DL_STAT= 0;
+               }
 
                if (mess1.DL_STAT & DL_PACK_RECV)
                {
@@ -781,15 +837,26 @@ eth_port_t *eth_port;
                        "setup_read(mess1): eth%d: got DL_PACK_RECV\n",
                                        mess1.DL_PORT);
                        }
-                       /* packet received */
-                       pack_ptr= bf_cut(pack, 0, mess1.DL_COUNT);
-                       bf_afree(pack);
-
-                       assert(!no_ethWritePort);
-                       no_ethWritePort= 1;
-                       eth_arrive(eth_port, pack_ptr, mess1.DL_COUNT);
-                       assert(no_ethWritePort);
-                       no_ethWritePort= 0;
+
+                       if (mess1.DL_COUNT < ETH_MIN_PACK_SIZE)
+                       {
+                               printf(
+                       "mnx_eth`setup_read: packet size too small (%d)\n",
+                                       mess1.DL_COUNT);
+                               bf_afree(pack);
+                       }
+                       else
+                       {
+                               /* packet received */
+                               pack_ptr= bf_cut(pack, 0, mess1.DL_COUNT);
+                               bf_afree(pack);
+
+                               assert(!no_ethWritePort);
+                               no_ethWritePort= 1;
+                               eth_arrive(eth_port, pack_ptr, mess1.DL_COUNT);
+                               assert(no_ethWritePort);
+                               no_ethWritePort= 0;
+                       }
                }
                else
                {
@@ -800,9 +867,20 @@ eth_port_t *eth_port;
 
                if (mess1.DL_STAT & DL_PACK_SEND)
                {
-                       eth_port->etp_osdep.etp_sendrepl= mess1;
-                       ev_arg.ev_ptr= eth_port;
-                       ev_enqueue(&eth_port->etp_sendev, eth_sendev, ev_arg);
+                       if (eth_port->etp_osdep.etp_send_ev)
+                       {
+                               printf(
+       "mnx_eth`setup_read: etp_send_ev is set, ignoring DL_PACK_SEND\n");
+                       }
+                       else
+                       {
+                               eth_port->etp_osdep.etp_sendrepl= mess1;
+                               ev_arg.ev_ptr= eth_port;
+                               assert(!eth_port->etp_osdep.etp_send_ev);
+                               eth_port->etp_osdep.etp_send_ev= 1;
+                               ev_enqueue(&eth_port->etp_sendev, eth_sendev,
+                                       ev_arg);
+                       }
                }
        } while (!(eth_port->etp_flags & EPF_READ_IP));
        eth_port->etp_flags |= EPF_READ_SP;
@@ -851,6 +929,8 @@ ev_arg_t ev_arg;
 
        assert(m_ptr->DL_STAT & DL_PACK_SEND);
        m_ptr->DL_STAT &= ~DL_PACK_SEND;
+       assert(eth_port->etp_osdep.etp_send_ev);
+       eth_port->etp_osdep.etp_send_ev= 0;
 
        /* packet is sent */
        write_int(eth_port);
index a31cc658616665378aaeced95fcc903d01dea7f7..0bfec142fb1f2f36b9710ca4b4691d0166295852 100644 (file)
@@ -19,6 +19,7 @@ typedef struct osdep_eth_port
        int etp_task;
        int etp_port;
        int etp_recvconf;
+       int etp_send_ev;
        iovec_s_t etp_wr_iovec[IOVEC_NR];
        cp_grant_id_t etp_wr_vec_grant;
        iovec_s_t etp_rd_iovec[RD_IOVEC];