Browse Source

Minirouting table entries hold a persistent reference to a net_device.

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
35b5e5d3f5
1 changed files with 91 additions and 16 deletions
  1. 91
    16
      src/net/ipv4.c

+ 91
- 16
src/net/ipv4.c View File

34
 struct ipv4_miniroute {
34
 struct ipv4_miniroute {
35
 	/** List of miniroutes */
35
 	/** List of miniroutes */
36
 	struct list_head list;
36
 	struct list_head list;
37
+
37
 	/** Network device */
38
 	/** Network device */
38
 	struct net_device *netdev;
39
 	struct net_device *netdev;
40
+	/** Reference to network device */
41
+	struct reference netdev_ref;
42
+
39
 	/** IPv4 address */
43
 	/** IPv4 address */
40
 	struct in_addr address;
44
 	struct in_addr address;
41
 	/** Subnet mask */
45
 	/** Subnet mask */
50
 /** List of fragment reassembly buffers */
54
 /** List of fragment reassembly buffers */
51
 static LIST_HEAD ( frag_buffers );
55
 static LIST_HEAD ( frag_buffers );
52
 
56
 
57
+static void ipv4_forget_netdev ( struct reference *ref );
58
+
59
+/**
60
+ * Add IPv4 minirouting table entry
61
+ *
62
+ * @v netdev		Network device
63
+ * @v address		IPv4 address
64
+ * @v netmask		Subnet mask
65
+ * @v gateway		Gateway address (or @c INADDR_NONE for no gateway)
66
+ * @ret miniroute	Routing table entry, or NULL
67
+ */
68
+static struct ipv4_miniroute * add_ipv4_miniroute ( struct net_device *netdev,
69
+						    struct in_addr address,
70
+						    struct in_addr netmask,
71
+						    struct in_addr gateway ) {
72
+	struct ipv4_miniroute *miniroute;
73
+
74
+	/* Allocate and populate miniroute structure */
75
+	miniroute = malloc ( sizeof ( *miniroute ) );
76
+	if ( miniroute ) {
77
+
78
+		DBG ( "IPv4 add %s", inet_ntoa ( address ) );
79
+		DBG ( "/%s ", inet_ntoa ( netmask ) );
80
+		if ( gateway.s_addr != INADDR_NONE )
81
+			DBG ( "gw %s ", inet_ntoa ( gateway ) );
82
+		DBG ( "via %s\n", netdev_name ( netdev ) );
83
+
84
+		/* Record routing information */
85
+		miniroute->netdev = netdev;
86
+		miniroute->address = address;
87
+		miniroute->netmask = netmask;
88
+		miniroute->gateway = gateway;
89
+		
90
+		/* Add to end of list if we have a gateway, otherwise
91
+		 * to start of list.
92
+		 */
93
+		if ( gateway.s_addr != INADDR_NONE ) {
94
+			list_add_tail ( &miniroute->list, &miniroutes );
95
+		} else {
96
+			list_add ( &miniroute->list, &miniroutes );
97
+		}
98
+
99
+		/* Record reference to net_device */
100
+		miniroute->netdev_ref.forget = ipv4_forget_netdev;
101
+		ref_add ( &miniroute->netdev_ref, &netdev->references );
102
+	}
103
+
104
+	return miniroute;
105
+}
106
+
107
+/**
108
+ * Delete IPv4 minirouting table entry
109
+ *
110
+ * @v miniroute		Routing table entry
111
+ */
112
+static void del_ipv4_miniroute ( struct ipv4_miniroute *miniroute ) {
113
+
114
+	DBG ( "IPv4 del %s", inet_ntoa ( miniroute->address ) );
115
+	DBG ( "/%s ", inet_ntoa ( miniroute->netmask ) );
116
+	if ( miniroute->gateway.s_addr != INADDR_NONE )
117
+		DBG ( "gw %s ", inet_ntoa ( miniroute->gateway ) );
118
+	DBG ( "via %s\n", netdev_name ( miniroute->netdev ) );
119
+
120
+	ref_del ( &miniroute->netdev_ref );
121
+	list_del ( &miniroute->list );
122
+	free ( miniroute );
123
+}
124
+
125
+/**
126
+ * Forget reference to net_device
127
+ *
128
+ * @v ref		Persistent reference
129
+ */
130
+static void ipv4_forget_netdev ( struct reference *ref ) {
131
+	struct ipv4_miniroute *miniroute
132
+		= container_of ( ref, struct ipv4_miniroute, netdev_ref );
133
+
134
+	del_ipv4_miniroute ( miniroute );
135
+}
136
+
53
 /**
137
 /**
54
  * Add IPv4 interface
138
  * Add IPv4 interface
55
  *
139
  *
64
 		       struct in_addr netmask, struct in_addr gateway ) {
148
 		       struct in_addr netmask, struct in_addr gateway ) {
65
 	struct ipv4_miniroute *miniroute;
149
 	struct ipv4_miniroute *miniroute;
66
 
150
 
67
-	/* Allocate and populate miniroute structure */
151
+	/* Clear any existing address for this net device */
68
-	miniroute = malloc ( sizeof ( *miniroute ) );
152
+	del_ipv4_address ( netdev );
153
+
154
+	/* Add new miniroute */
155
+	miniroute = add_ipv4_miniroute ( netdev, address, netmask, gateway );
69
 	if ( ! miniroute )
156
 	if ( ! miniroute )
70
 		return -ENOMEM;
157
 		return -ENOMEM;
71
-	miniroute->netdev = netdev;
158
+
72
-	miniroute->address = address;
73
-	miniroute->netmask = netmask;
74
-	miniroute->gateway = gateway;
75
-	
76
-	/* Add to end of list if we have a gateway, otherwise to start
77
-	 * of list.
78
-	 */
79
-	if ( gateway.s_addr != INADDR_NONE ) {
80
-		list_add_tail ( &miniroute->list, &miniroutes );
81
-	} else {
82
-		list_add ( &miniroute->list, &miniroutes );
83
-	}
84
 	return 0;
159
 	return 0;
85
 }
160
 }
86
 
161
 
94
 
169
 
95
 	list_for_each_entry ( miniroute, &miniroutes, list ) {
170
 	list_for_each_entry ( miniroute, &miniroutes, list ) {
96
 		if ( miniroute->netdev == netdev ) {
171
 		if ( miniroute->netdev == netdev ) {
97
-			list_del ( &miniroute->list );
172
+			del_ipv4_miniroute ( miniroute );
98
 			break;
173
 			break;
99
 		}
174
 		}
100
 	}
175
 	}

Loading…
Cancel
Save