Procházet zdrojové kódy

IPv6 minirouting table entries hold persistent references to net devices.

tags/v0.9.3
Michael Brown před 17 roky
rodič
revize
b29861a5aa
2 změnil soubory, kde provedl 83 přidání a 17 odebrání
  1. 5
    0
      src/include/gpxe/ip6.h
  2. 78
    17
      src/net/ipv6.c

+ 5
- 0
src/include/gpxe/ip6.h Zobrazit soubor

@@ -69,5 +69,10 @@ extern struct net_protocol ipv6_protocol;
69 69
 extern struct tcpip_net_protocol ipv6_tcpip_protocol;
70 70
 extern char * inet6_ntoa ( struct in6_addr in6 );
71 71
 
72
+extern int add_ipv6_address ( struct net_device *netdev,
73
+			      struct in6_addr prefix, int prefix_len,
74
+			      struct in6_addr address,
75
+			      struct in6_addr gateway );
76
+extern void del_ipv6_address ( struct net_device *netdev );
72 77
 
73 78
 #endif /* _GPXE_IP6_H */

+ 78
- 17
src/net/ipv6.c Zobrazit soubor

@@ -30,8 +30,12 @@ static struct in6_addr ip6_none = {
30 30
 struct ipv6_miniroute {
31 31
 	/* List of miniroutes */
32 32
 	struct list_head list;
33
+
33 34
 	/* Network device */
34 35
 	struct net_device *netdev;
36
+	/** Reference to network device */
37
+	struct reference netdev_ref;
38
+
35 39
 	/* Destination prefix */
36 40
 	struct in6_addr prefix;
37 41
 	/* Prefix length */
@@ -45,6 +49,71 @@ struct ipv6_miniroute {
45 49
 /** List of IPv6 miniroutes */
46 50
 static LIST_HEAD ( miniroutes );
47 51
 
52
+static void ipv6_forget_netdev ( struct reference *ref );
53
+
54
+/**
55
+ * Add IPv6 minirouting table entry
56
+ *
57
+ * @v netdev		Network device
58
+ * @v prefix		Destination prefix
59
+ * @v address		Address of the interface
60
+ * @v gateway		Gateway address (or ::0 for no gateway)
61
+ * @ret miniroute	Routing table entry, or NULL
62
+ */
63
+static struct ipv6_miniroute * add_ipv6_miniroute ( struct net_device *netdev,
64
+						    struct in6_addr prefix,
65
+						    int prefix_len,
66
+						    struct in6_addr address,
67
+						    struct in6_addr gateway ) {
68
+	struct ipv6_miniroute *miniroute;
69
+	
70
+	miniroute = malloc ( sizeof ( *miniroute ) );
71
+	if ( miniroute ) {
72
+		/* Record routing information */
73
+		miniroute->netdev = netdev;
74
+		miniroute->prefix = prefix;
75
+		miniroute->prefix_len = prefix_len;
76
+		miniroute->address = address;
77
+		miniroute->gateway = gateway;
78
+		
79
+		/* Add miniroute to list of miniroutes */
80
+		if ( !IP6_EQUAL ( gateway, ip6_none ) ) {
81
+			list_add_tail ( &miniroute->list, &miniroutes );
82
+		} else {
83
+			list_add ( &miniroute->list, &miniroutes );
84
+		}
85
+
86
+		/* Record reference to net_device */
87
+		miniroute->netdev_ref.forget = ipv6_forget_netdev;
88
+		ref_add ( &miniroute->netdev_ref, &netdev->references );
89
+	}
90
+
91
+	return miniroute;
92
+}
93
+
94
+/**
95
+ * Delete IPv6 minirouting table entry
96
+ *
97
+ * @v miniroute		Routing table entry
98
+ */
99
+static void del_ipv6_miniroute ( struct ipv6_miniroute *miniroute ) {
100
+	ref_del ( &miniroute->netdev_ref );
101
+	list_del ( &miniroute->list );
102
+	free ( miniroute );
103
+}
104
+
105
+/**
106
+ * Forget reference to net_device
107
+ *
108
+ * @v ref		Persistent reference
109
+ */
110
+static void ipv6_forget_netdev ( struct reference *ref ) {
111
+	struct ipv6_miniroute *miniroute
112
+		= container_of ( ref, struct ipv6_miniroute, netdev_ref );
113
+
114
+	del_ipv6_miniroute ( miniroute );
115
+}
116
+
48 117
 /**
49 118
  * Add IPv6 interface
50 119
  *
@@ -58,23 +127,15 @@ int add_ipv6_address ( struct net_device *netdev, struct in6_addr prefix,
58 127
 		       struct in6_addr gateway ) {
59 128
 	struct ipv6_miniroute *miniroute;
60 129
 
61
-	miniroute = malloc ( sizeof ( *miniroute ) );
62
-	if ( !miniroute ) {
63
-		DBG ( "Not enough memory\n" );
130
+	/* Clear any existing address for this net device */
131
+	del_ipv6_address ( netdev );
132
+
133
+	/* Add new miniroute */
134
+	miniroute = add_ipv6_miniroute ( netdev, prefix, prefix_len, address,
135
+					 gateway );
136
+	if ( ! miniroute )
64 137
 		return -ENOMEM;
65
-	}
66
-	miniroute->netdev = netdev;
67
-	miniroute->prefix = prefix;
68
-	miniroute->prefix_len = prefix_len;
69
-	miniroute->address = address;
70
-	miniroute->gateway = gateway;
71
-
72
-	/* Add miniroute to list of miniroutes */
73
-	if ( !IP6_EQUAL ( gateway, ip6_none ) ) {
74
-		list_add_tail ( &miniroute->list, &miniroutes );
75
-	} else {
76
-		list_add ( &miniroute->list, &miniroutes );
77
-	}
138
+
78 139
 	return 0;
79 140
 }
80 141
 
@@ -88,7 +149,7 @@ void del_ipv6_address ( struct net_device *netdev ) {
88 149
 
89 150
 	list_for_each_entry ( miniroute, &miniroutes, list ) {
90 151
 		if ( miniroute->netdev == netdev ) {
91
-			list_del ( &miniroute->list );
152
+			del_ipv6_miniroute ( miniroute );
92 153
 			break;
93 154
 		}
94 155
 	}

Načítá se…
Zrušit
Uložit