summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/aoe.c17
-rw-r--r--src/net/ipv4.c22
-rw-r--r--src/net/ipv6.c24
-rw-r--r--src/net/netdevice.c74
-rw-r--r--src/net/udp.c2
-rw-r--r--src/net/udp/dhcp.c25
6 files changed, 59 insertions, 105 deletions
diff --git a/src/net/aoe.c b/src/net/aoe.c
index 084a3d4d8..36721df64 100644
--- a/src/net/aoe.c
+++ b/src/net/aoe.c
@@ -266,19 +266,6 @@ struct net_protocol aoe_protocol __net_protocol = {
};
/**
- * Forget reference to net_device
- *
- * @v ref Persistent reference
- */
-static void aoe_forget_netdev ( struct reference *ref ) {
- struct aoe_session *aoe
- = container_of ( ref, struct aoe_session, netdev_ref );
-
- aoe->netdev = NULL;
- ref_del ( &aoe->netdev_ref );
-}
-
-/**
* Open AoE session
*
* @v aoe AoE session
@@ -288,8 +275,6 @@ void aoe_open ( struct aoe_session *aoe ) {
sizeof ( aoe->target ) );
aoe->tag = AOE_TAG_MAGIC;
aoe->timer.expired = aoe_timer_expired;
- aoe->netdev_ref.forget = aoe_forget_netdev;
- ref_add ( &aoe->netdev_ref, &aoe->netdev->references );
list_add ( &aoe->list, &aoe_sessions );
}
@@ -299,8 +284,6 @@ void aoe_open ( struct aoe_session *aoe ) {
* @v aoe AoE session
*/
void aoe_close ( struct aoe_session *aoe ) {
- if ( aoe->netdev )
- ref_del ( &aoe->netdev_ref );
list_del ( &aoe->list );
}
diff --git a/src/net/ipv4.c b/src/net/ipv4.c
index a6fb65edd..e1219edb6 100644
--- a/src/net/ipv4.c
+++ b/src/net/ipv4.c
@@ -30,8 +30,6 @@ struct list_head ipv4_miniroutes = LIST_HEAD_INIT ( ipv4_miniroutes );
/** List of fragment reassembly buffers */
static LIST_HEAD ( frag_buffers );
-static void ipv4_forget_netdev ( struct reference *ref );
-
/**
* Add IPv4 minirouting table entry
*
@@ -61,7 +59,7 @@ static struct ipv4_miniroute * add_ipv4_miniroute ( struct net_device *netdev,
}
/* Record routing information */
- miniroute->netdev = netdev;
+ miniroute->netdev = netdev_get ( netdev );
miniroute->address = address;
miniroute->netmask = netmask;
miniroute->gateway = gateway;
@@ -75,10 +73,6 @@ static struct ipv4_miniroute * add_ipv4_miniroute ( struct net_device *netdev,
list_add ( &miniroute->list, &ipv4_miniroutes );
}
- /* Record reference to net_device */
- miniroute->netdev_ref.forget = ipv4_forget_netdev;
- ref_add ( &miniroute->netdev_ref, &netdev->references );
-
return miniroute;
}
@@ -95,24 +89,12 @@ static void del_ipv4_miniroute ( struct ipv4_miniroute *miniroute ) {
DBG ( "gw %s ", inet_ntoa ( miniroute->gateway ) );
DBG ( "via %s\n", miniroute->netdev->name );
- ref_del ( &miniroute->netdev_ref );
+ netdev_put ( miniroute->netdev );
list_del ( &miniroute->list );
free ( miniroute );
}
/**
- * Forget reference to net_device
- *
- * @v ref Persistent reference
- */
-static void ipv4_forget_netdev ( struct reference *ref ) {
- struct ipv4_miniroute *miniroute
- = container_of ( ref, struct ipv4_miniroute, netdev_ref );
-
- del_ipv4_miniroute ( miniroute );
-}
-
-/**
* Add IPv4 interface
*
* @v netdev Network device
diff --git a/src/net/ipv6.c b/src/net/ipv6.c
index 98e1631d6..86074065f 100644
--- a/src/net/ipv6.c
+++ b/src/net/ipv6.c
@@ -32,8 +32,6 @@ struct ipv6_miniroute {
/* Network device */
struct net_device *netdev;
- /** Reference to network device */
- struct reference netdev_ref;
/* Destination prefix */
struct in6_addr prefix;
@@ -48,8 +46,6 @@ struct ipv6_miniroute {
/** List of IPv6 miniroutes */
static LIST_HEAD ( miniroutes );
-static void ipv6_forget_netdev ( struct reference *ref );
-
/**
* Add IPv6 minirouting table entry
*
@@ -69,7 +65,7 @@ static struct ipv6_miniroute * add_ipv6_miniroute ( struct net_device *netdev,
miniroute = malloc ( sizeof ( *miniroute ) );
if ( miniroute ) {
/* Record routing information */
- miniroute->netdev = netdev;
+ miniroute->netdev = netdev_get ( netdev );
miniroute->prefix = prefix;
miniroute->prefix_len = prefix_len;
miniroute->address = address;
@@ -81,10 +77,6 @@ static struct ipv6_miniroute * add_ipv6_miniroute ( struct net_device *netdev,
} else {
list_add ( &miniroute->list, &miniroutes );
}
-
- /* Record reference to net_device */
- miniroute->netdev_ref.forget = ipv6_forget_netdev;
- ref_add ( &miniroute->netdev_ref, &netdev->references );
}
return miniroute;
@@ -96,24 +88,12 @@ static struct ipv6_miniroute * add_ipv6_miniroute ( struct net_device *netdev,
* @v miniroute Routing table entry
*/
static void del_ipv6_miniroute ( struct ipv6_miniroute *miniroute ) {
- ref_del ( &miniroute->netdev_ref );
+ netdev_put ( miniroute->netdev );
list_del ( &miniroute->list );
free ( miniroute );
}
/**
- * Forget reference to net_device
- *
- * @v ref Persistent reference
- */
-static void ipv6_forget_netdev ( struct reference *ref ) {
- struct ipv6_miniroute *miniroute
- = container_of ( ref, struct ipv6_miniroute, netdev_ref );
-
- del_ipv6_miniroute ( miniroute );
-}
-
-/**
* Add IPv6 interface
*
* @v netdev Network device
diff --git a/src/net/netdevice.c b/src/net/netdevice.c
index ddcb296f4..294f07869 100644
--- a/src/net/netdevice.c
+++ b/src/net/netdevice.c
@@ -116,6 +116,19 @@ void netdev_tx_complete_next ( struct net_device *netdev ) {
}
/**
+ * Flush device's transmit queue
+ *
+ * @v netdev Network device
+ */
+static void netdev_tx_flush ( struct net_device *netdev ) {
+
+ /* Discard any packets in the TX queue */
+ while ( ! list_empty ( &netdev->tx_queue ) ) {
+ netdev_tx_complete_next ( netdev );
+ }
+}
+
+/**
* Add packet to receive queue
*
* @v netdev Network device
@@ -169,6 +182,36 @@ struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev ) {
}
/**
+ * Flush device's receive queue
+ *
+ * @v netdev Network device
+ */
+static void netdev_rx_flush ( struct net_device *netdev ) {
+ struct io_buffer *iobuf;
+
+ /* Discard any packets in the RX queue */
+ while ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
+ DBGC ( netdev, "NETDEV %p discarding received %p\n",
+ netdev, iobuf );
+ free_iob ( iobuf );
+ }
+}
+
+/**
+ * Free network device
+ *
+ * @v refcnt Network device reference counter
+ */
+static void free_netdev ( struct refcnt *refcnt ) {
+ struct net_device *netdev =
+ container_of ( refcnt, struct net_device, refcnt );
+
+ netdev_tx_flush ( netdev );
+ netdev_rx_flush ( netdev );
+ free ( netdev );
+}
+
+/**
* Allocate network device
*
* @v priv_size Size of private data area (net_device::priv)
@@ -184,7 +227,7 @@ struct net_device * alloc_netdev ( size_t priv_size ) {
netdev = malloc ( total_len );
if ( netdev ) {
memset ( netdev, 0, total_len );
- INIT_LIST_HEAD ( &netdev->references );
+ netdev->refcnt.free = free_netdev;
INIT_LIST_HEAD ( &netdev->tx_queue );
INIT_LIST_HEAD ( &netdev->rx_queue );
netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
@@ -209,6 +252,7 @@ int register_netdev ( struct net_device *netdev ) {
ifindex++ );
/* Add to device list */
+ netdev_get ( netdev );
list_add_tail ( &netdev->list, &net_devices );
DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
netdev, netdev->name, netdev->dev->name,
@@ -247,7 +291,6 @@ int netdev_open ( struct net_device *netdev ) {
* @v netdev Network device
*/
void netdev_close ( struct net_device *netdev ) {
- struct io_buffer *iobuf;
/* Do nothing if device is already closed */
if ( ! ( netdev->state & NETDEV_OPEN ) )
@@ -258,17 +301,9 @@ void netdev_close ( struct net_device *netdev ) {
/* Close the device */
netdev->close ( netdev );
- /* Discard any packets in the TX queue */
- while ( ! list_empty ( &netdev->tx_queue ) ) {
- netdev_tx_complete_next ( netdev );
- }
-
- /* Discard any packets in the RX queue */
- while ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
- DBGC ( netdev, "NETDEV %p discarding received %p\n",
- netdev, iobuf );
- free_iob ( iobuf );
- }
+ /* Flush TX and RX queues */
+ netdev_tx_flush ( netdev );
+ netdev_rx_flush ( netdev );
/* Mark as closed */
netdev->state &= ~NETDEV_OPEN;
@@ -286,24 +321,13 @@ void unregister_netdev ( struct net_device *netdev ) {
/* Ensure device is closed */
netdev_close ( netdev );
- /* Kill off any persistent references to this device */
- forget_references ( &netdev->references );
-
/* Remove from device list */
list_del ( &netdev->list );
+ netdev_put ( netdev );
DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
}
/**
- * Free network device
- *
- * @v netdev Network device
- */
-void free_netdev ( struct net_device *netdev ) {
- free ( netdev );
-}
-
-/**
* Get network device by name
*
* @v name Network device name
diff --git a/src/net/udp.c b/src/net/udp.c
index ca0c816fe..404dd7276 100644
--- a/src/net/udp.c
+++ b/src/net/udp.c
@@ -140,7 +140,7 @@ static int udp_open_common ( struct xfer_interface *xfer,
* @ret rc Return status code
*/
int udp_open ( struct xfer_interface *xfer, struct sockaddr *peer,
- struct sockaddr *local ) {
+ struct sockaddr *local ) {
return udp_open_common ( xfer, peer, local, 0 );
}
diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c
index 2caea335e..4ecb17bfa 100644
--- a/src/net/udp/dhcp.c
+++ b/src/net/udp/dhcp.c
@@ -493,6 +493,8 @@ udp_to_dhcp ( struct udp_connection *conn ) {
return container_of ( conn, struct dhcp_session, udp );
}
+#if 0
+
/**
* Mark DHCP session as complete
*
@@ -515,9 +517,6 @@ static void dhcp_done ( struct dhcp_session *dhcp, int rc ) {
/* Close UDP connection */
udp_close ( &dhcp->udp );
- /* Release reference on net device */
- ref_del ( &dhcp->netdev_ref );
-
/* Mark async operation as complete */
async_done ( &dhcp->async, rc );
}
@@ -706,19 +705,6 @@ static struct udp_operations dhcp_udp_operations = {
};
/**
- * Forget reference to net_device
- *
- * @v ref Persistent reference
- */
-static void dhcp_forget_netdev ( struct reference *ref ) {
- struct dhcp_session *dhcp
- = container_of ( ref, struct dhcp_session, netdev_ref );
-
- /* Kill DHCP session immediately */
- dhcp_done ( dhcp, -ENETUNREACH );
-}
-
-/**
* Initiate DHCP on a network interface
*
* @v dhcp DHCP session
@@ -742,13 +728,12 @@ int start_dhcp ( struct dhcp_session *dhcp, struct async *parent ) {
if ( ( rc = udp_open ( &dhcp->udp, htons ( BOOTPC_PORT ) ) ) != 0 )
return rc;
- /* Add persistent reference to net device */
- dhcp->netdev_ref.forget = dhcp_forget_netdev;
- ref_add ( &dhcp->netdev_ref, &dhcp->netdev->references );
-
/* Proof of concept: just send a single DHCPDISCOVER */
dhcp_send_request ( dhcp );
async_init ( &dhcp->async, &default_async_operations, parent );
return 0;
}
+
+
+#endif