Ver código fonte

[tcpip] Provide tcpip_netdev() to determine the transmitting network device

Provide the function tcpip_netdev() to allow external code to
determine the transmitting network device for a given socket address.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 anos atrás
pai
commit
db67de6f31
4 arquivos alterados com 94 adições e 10 exclusões
  1. 8
    0
      src/include/ipxe/tcpip.h
  2. 20
    0
      src/net/ipv4.c
  3. 20
    0
      src/net/ipv6.c
  4. 46
    10
      src/net/tcpip.c

+ 8
- 0
src/include/ipxe/tcpip.h Ver arquivo

@@ -116,6 +116,13 @@ struct tcpip_net_protocol {
116 116
 		       struct sockaddr_tcpip *st_dest,
117 117
 		       struct net_device *netdev,
118 118
 		       uint16_t *trans_csum );
119
+	/**
120
+	 * Determine transmitting network device
121
+	 *
122
+	 * @v st_dest		Destination address
123
+	 * @ret netdev		Network device, or NULL
124
+	 */
125
+	struct net_device * ( * netdev ) ( struct sockaddr_tcpip *dest );
119 126
 };
120 127
 
121 128
 /** TCP/IP transport-layer protocol table */
@@ -140,6 +147,7 @@ extern int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip,
140 147
 		      struct sockaddr_tcpip *st_dest,
141 148
 		      struct net_device *netdev,
142 149
 		      uint16_t *trans_csum );
150
+extern struct net_device * tcpip_netdev ( struct sockaddr_tcpip *st_dest );
143 151
 extern uint16_t generic_tcpip_continue_chksum ( uint16_t partial,
144 152
 						const void *data, size_t len );
145 153
 extern uint16_t tcpip_chksum ( const void *data, size_t len );

+ 20
- 0
src/net/ipv4.c Ver arquivo

@@ -137,6 +137,25 @@ static struct ipv4_miniroute * ipv4_route ( struct in_addr *dest ) {
137 137
 	return NULL;
138 138
 }
139 139
 
140
+/**
141
+ * Determine transmitting network device
142
+ *
143
+ * @v st_dest		Destination network-layer address
144
+ * @ret netdev		Transmitting network device, or NULL
145
+ */
146
+static struct net_device * ipv4_netdev ( struct sockaddr_tcpip *st_dest ) {
147
+	struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
148
+	struct in_addr dest = sin_dest->sin_addr;
149
+	struct ipv4_miniroute *miniroute;
150
+
151
+	/* Find routing table entry */
152
+	miniroute = ipv4_route ( &dest );
153
+	if ( ! miniroute )
154
+		return NULL;
155
+
156
+	return miniroute->netdev;
157
+}
158
+
140 159
 /**
141 160
  * Check if IPv4 fragment matches fragment reassembly buffer
142 161
  *
@@ -603,6 +622,7 @@ struct tcpip_net_protocol ipv4_tcpip_protocol __tcpip_net_protocol = {
603 622
 	.name = "IPv4",
604 623
 	.sa_family = AF_INET,
605 624
 	.tx = ipv4_tx,
625
+	.netdev = ipv4_netdev,
606 626
 };
607 627
 
608 628
 /** IPv4 ARP protocol */

+ 20
- 0
src/net/ipv6.c Ver arquivo

@@ -321,6 +321,25 @@ static struct ipv6_miniroute * ipv6_route ( unsigned int scope_id,
321 321
 	return NULL;
322 322
 }
323 323
 
324
+/**
325
+ * Determine transmitting network device
326
+ *
327
+ * @v st_dest		Destination network-layer address
328
+ * @ret netdev		Transmitting network device, or NULL
329
+ */
330
+static struct net_device * ipv6_netdev ( struct sockaddr_tcpip *st_dest ) {
331
+	struct sockaddr_in6 *sin6_dest = ( ( struct sockaddr_in6 * ) st_dest );
332
+	struct in6_addr *dest = &sin6_dest->sin6_addr;
333
+	struct ipv6_miniroute *miniroute;
334
+
335
+	/* Find routing table entry */
336
+	miniroute = ipv6_route ( sin6_dest->sin6_scope_id, &dest );
337
+	if ( ! miniroute )
338
+		return NULL;
339
+
340
+	return miniroute->netdev;
341
+}
342
+
324 343
 /**
325 344
  * Check that received options can be safely ignored
326 345
  *
@@ -970,6 +989,7 @@ struct tcpip_net_protocol ipv6_tcpip_protocol __tcpip_net_protocol = {
970 989
 	.name = "IPv6",
971 990
 	.sa_family = AF_INET6,
972 991
 	.tx = ipv6_tx,
992
+	.netdev = ipv6_netdev,
973 993
 };
974 994
 
975 995
 /** IPv6 socket address converter */

+ 46
- 10
src/net/tcpip.c Ver arquivo

@@ -18,7 +18,8 @@
18 18
 
19 19
 FILE_LICENCE ( GPL2_OR_LATER );
20 20
 
21
-/** Process a received TCP/IP packet
21
+/**
22
+ * Process a received TCP/IP packet
22 23
  *
23 24
  * @v iobuf		I/O buffer
24 25
  * @v netdev		Network device
@@ -57,7 +58,27 @@ int tcpip_rx ( struct io_buffer *iobuf, struct net_device *netdev,
57 58
 	return -EPROTONOSUPPORT;
58 59
 }
59 60
 
60
-/** Transmit a TCP/IP packet
61
+/**
62
+ * Find TCP/IP network-layer protocol
63
+ *
64
+ * @v st_dest		Destination address
65
+ * @ret tcpip_net	TCP/IP network-layer protocol, or NULL if not found
66
+ */
67
+static struct tcpip_net_protocol *
68
+tcpip_net_protocol ( struct sockaddr_tcpip *st_dest ) {
69
+	struct tcpip_net_protocol *tcpip_net;
70
+
71
+	for_each_table_entry ( tcpip_net, TCPIP_NET_PROTOCOLS ) {
72
+		if ( tcpip_net->sa_family == st_dest->st_family )
73
+			return tcpip_net;
74
+	}
75
+
76
+	DBG ( "Unrecognised TCP/IP address family %d\n", st_dest->st_family );
77
+	return NULL;
78
+}
79
+
80
+/**
81
+ * Transmit a TCP/IP packet
61 82
  *
62 83
  * @v iobuf		I/O buffer
63 84
  * @v tcpip_protocol	Transport-layer protocol
@@ -73,19 +94,34 @@ int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol,
73 94
 	struct tcpip_net_protocol *tcpip_net;
74 95
 
75 96
 	/* Hand off packet to the appropriate network-layer protocol */
76
-	for_each_table_entry ( tcpip_net, TCPIP_NET_PROTOCOLS ) {
77
-		if ( tcpip_net->sa_family == st_dest->st_family ) {
78
-			DBG ( "TCP/IP sending %s packet\n", tcpip_net->name );
79
-			return tcpip_net->tx ( iobuf, tcpip_protocol, st_src,
80
-					       st_dest, netdev, trans_csum );
81
-		}
97
+	tcpip_net = tcpip_net_protocol ( st_dest );
98
+	if ( tcpip_net ) {
99
+		DBG ( "TCP/IP sending %s packet\n", tcpip_net->name );
100
+		return tcpip_net->tx ( iobuf, tcpip_protocol, st_src, st_dest,
101
+				       netdev, trans_csum );
82 102
 	}
83
-	
84
-	DBG ( "Unrecognised TCP/IP address family %d\n", st_dest->st_family );
103
+
85 104
 	free_iob ( iobuf );
86 105
 	return -EAFNOSUPPORT;
87 106
 }
88 107
 
108
+/**
109
+ * Determine transmitting network device
110
+ *
111
+ * @v st_dest		Destination address
112
+ * @ret netdev		Network device, or NULL
113
+ */
114
+struct net_device * tcpip_netdev ( struct sockaddr_tcpip *st_dest ) {
115
+	struct tcpip_net_protocol *tcpip_net;
116
+
117
+	/* Hand off to the appropriate network-layer protocol */
118
+	tcpip_net = tcpip_net_protocol ( st_dest );
119
+	if ( tcpip_net )
120
+		return tcpip_net->netdev ( st_dest );
121
+
122
+	return NULL;
123
+}
124
+
89 125
 /**
90 126
  * Calculate continued TCP/IP checkum
91 127
  *

Carregando…
Cancelar
Salvar