Przeglądaj źródła

Minirouting table entries hold a persistent reference to a net_device.

tags/v0.9.3
Michael Brown 18 lat temu
rodzic
commit
35b5e5d3f5
1 zmienionych plików z 91 dodań i 16 usunięć
  1. 91
    16
      src/net/ipv4.c

+ 91
- 16
src/net/ipv4.c Wyświetl plik

@@ -34,8 +34,12 @@ struct net_protocol ipv4_protocol;
34 34
 struct ipv4_miniroute {
35 35
 	/** List of miniroutes */
36 36
 	struct list_head list;
37
+
37 38
 	/** Network device */
38 39
 	struct net_device *netdev;
40
+	/** Reference to network device */
41
+	struct reference netdev_ref;
42
+
39 43
 	/** IPv4 address */
40 44
 	struct in_addr address;
41 45
 	/** Subnet mask */
@@ -50,6 +54,86 @@ static LIST_HEAD ( miniroutes );
50 54
 /** List of fragment reassembly buffers */
51 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 138
  * Add IPv4 interface
55 139
  *
@@ -64,23 +148,14 @@ int add_ipv4_address ( struct net_device *netdev, struct in_addr address,
64 148
 		       struct in_addr netmask, struct in_addr gateway ) {
65 149
 	struct ipv4_miniroute *miniroute;
66 150
 
67
-	/* Allocate and populate miniroute structure */
68
-	miniroute = malloc ( sizeof ( *miniroute ) );
151
+	/* Clear any existing address for this net device */
152
+	del_ipv4_address ( netdev );
153
+
154
+	/* Add new miniroute */
155
+	miniroute = add_ipv4_miniroute ( netdev, address, netmask, gateway );
69 156
 	if ( ! miniroute )
70 157
 		return -ENOMEM;
71
-	miniroute->netdev = netdev;
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
-	}
158
+
84 159
 	return 0;
85 160
 }
86 161
 
@@ -94,7 +169,7 @@ void del_ipv4_address ( struct net_device *netdev ) {
94 169
 
95 170
 	list_for_each_entry ( miniroute, &miniroutes, list ) {
96 171
 		if ( miniroute->netdev == netdev ) {
97
-			list_del ( &miniroute->list );
172
+			del_ipv4_miniroute ( miniroute );
98 173
 			break;
99 174
 		}
100 175
 	}

Ładowanie…
Anuluj
Zapisz