Browse Source

Allow an explicit network device to be specified for IP-layer

transmissions.
tags/v0.9.3
Michael Brown 17 years ago
parent
commit
f008b77ba2
7 changed files with 32 additions and 17 deletions
  1. 8
    2
      src/include/gpxe/tcpip.h
  2. 2
    1
      src/net/icmpv6.c
  3. 12
    8
      src/net/ipv4.c
  4. 1
    1
      src/net/ipv6.c
  5. 4
    2
      src/net/tcp.c
  6. 4
    2
      src/net/tcpip.c
  7. 1
    1
      src/net/udp.c

+ 8
- 2
src/include/gpxe/tcpip.h View File

@@ -13,6 +13,7 @@
13 13
 #include <gpxe/tables.h>
14 14
 
15 15
 struct pk_buff;
16
+struct net_device;
16 17
 
17 18
 /** Empty checksum value
18 19
  *
@@ -84,6 +85,7 @@ struct tcpip_net_protocol {
84 85
 	 * @v pkb		Packet buffer
85 86
 	 * @v tcpip_protocol	Transport-layer protocol
86 87
 	 * @v st_dest		Destination address
88
+	 * @v netdev		Network device (or NULL to route automatically)
87 89
 	 * @v trans_csum	Transport-layer checksum to complete, or NULL
88 90
 	 * @ret rc		Return status code
89 91
 	 *
@@ -91,7 +93,9 @@ struct tcpip_net_protocol {
91 93
 	 */
92 94
 	int ( * tx ) ( struct pk_buff *pkb,
93 95
 		       struct tcpip_protocol *tcpip_protocol,
94
-		       struct sockaddr_tcpip *st_dest, uint16_t *trans_csum );
96
+		       struct sockaddr_tcpip *st_dest,
97
+		       struct net_device *netdev,
98
+		       uint16_t *trans_csum );
95 99
 };
96 100
 
97 101
 /** Declare a TCP/IP transport-layer protocol */
@@ -104,7 +108,9 @@ extern int tcpip_rx ( struct pk_buff *pkb, uint8_t tcpip_proto,
104 108
 		      struct sockaddr_tcpip *st_src,
105 109
 		      struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum );
106 110
 extern int tcpip_tx ( struct pk_buff *pkb, struct tcpip_protocol *tcpip, 
107
-		      struct sockaddr_tcpip *st_dest, uint16_t *trans_csum );
111
+		      struct sockaddr_tcpip *st_dest,
112
+		      struct net_device *netdev,
113
+		      uint16_t *trans_csum );
108 114
 extern uint16_t tcpip_continue_chksum ( uint16_t partial,
109 115
 					const void *data, size_t len );
110 116
 extern uint16_t tcpip_chksum ( const void *data, size_t len );

+ 2
- 1
src/net/icmpv6.c View File

@@ -60,7 +60,8 @@ int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src __unuse
60 60
 	st_dest.sin6.sin6_addr.in6_u.u6_addr8[13] = 0xff;
61 61
 	
62 62
 	/* Send packet over IP6 */
63
-	return tcpip_tx ( pkb, &icmp6_protocol, &st_dest.st, &nsolicit->csum );
63
+	return tcpip_tx ( pkb, &icmp6_protocol, &st_dest.st,
64
+			  NULL, &nsolicit->csum );
64 65
 }
65 66
 
66 67
 /**

+ 12
- 8
src/net/ipv4.c View File

@@ -372,6 +372,7 @@ static int ipv4_ll_addr ( struct in_addr dest, struct in_addr src,
372 372
  * @v pkb		Packet buffer
373 373
  * @v tcpip		Transport-layer protocol
374 374
  * @v st_dest		Destination network-layer address
375
+ * @v netdev		Network device (or NULL to route automatically)
375 376
  * @v trans_csum	Transport-layer checksum to complete, or NULL
376 377
  * @ret rc		Status
377 378
  *
@@ -379,7 +380,9 @@ static int ipv4_ll_addr ( struct in_addr dest, struct in_addr src,
379 380
  */
380 381
 static int ipv4_tx ( struct pk_buff *pkb,
381 382
 		     struct tcpip_protocol *tcpip_protocol,
382
-		     struct sockaddr_tcpip *st_dest, uint16_t *trans_csum ) {
383
+		     struct sockaddr_tcpip *st_dest,
384
+		     struct net_device *netdev,
385
+		     uint16_t *trans_csum ) {
383 386
 	struct iphdr *iphdr = pkb_push ( pkb, sizeof ( *iphdr ) );
384 387
 	struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
385 388
 	struct ipv4_miniroute *miniroute;
@@ -388,28 +391,29 @@ static int ipv4_tx ( struct pk_buff *pkb,
388 391
 	int rc;
389 392
 
390 393
 	/* Fill up the IP header, except source address */
394
+	memset ( iphdr, 0, sizeof ( *iphdr ) );
391 395
 	iphdr->verhdrlen = ( IP_VER | ( sizeof ( *iphdr ) / 4 ) );
392 396
 	iphdr->service = IP_TOS;
393 397
 	iphdr->len = htons ( pkb_len ( pkb ) );	
394 398
 	iphdr->ident = htons ( ++next_ident );
395
-	iphdr->frags = 0;
396 399
 	iphdr->ttl = IP_TTL;
397 400
 	iphdr->protocol = tcpip_protocol->tcpip_proto;
398
-	iphdr->chksum = 0;
399 401
 	iphdr->dest = sin_dest->sin_addr;
400 402
 
401 403
 	/* Use routing table to identify next hop and transmitting netdev */
402 404
 	next_hop = iphdr->dest;
403
-	miniroute = ipv4_route ( &next_hop );
404
-	if ( ! miniroute ) {
405
+	if ( ( miniroute = ipv4_route ( &next_hop ) ) ) {
406
+		iphdr->src = miniroute->address;
407
+		netdev = miniroute->netdev;
408
+	}
409
+	if ( ! netdev ) {
405 410
 		DBG ( "IPv4 has no route to %s\n", inet_ntoa ( iphdr->dest ) );
406 411
 		rc = -EHOSTUNREACH;
407 412
 		goto err;
408 413
 	}
409
-	iphdr->src = miniroute->address;
410 414
 
411 415
 	/* Determine link-layer destination address */
412
-	if ( ( rc = ipv4_ll_addr ( next_hop, iphdr->src, miniroute->netdev,
416
+	if ( ( rc = ipv4_ll_addr ( next_hop, iphdr->src, netdev,
413 417
 				   ll_dest ) ) != 0 ) {
414 418
 		DBG ( "IPv4 has no link-layer address for %s\n",
415 419
 		      inet_ntoa ( iphdr->dest ) );
@@ -428,7 +432,7 @@ static int ipv4_tx ( struct pk_buff *pkb,
428 432
 	      ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) );
429 433
 
430 434
 	/* Hand off to link layer */
431
-	return net_tx ( pkb, miniroute->netdev, &ipv4_protocol, ll_dest );
435
+	return net_tx ( pkb, netdev, &ipv4_protocol, ll_dest );
432 436
 
433 437
  err:
434 438
 	free_pkb ( pkb );

+ 1
- 1
src/net/ipv6.c View File

@@ -202,11 +202,11 @@ void ipv6_dump ( struct ip6_header *ip6hdr ) {
202 202
 static int ipv6_tx ( struct pk_buff *pkb,
203 203
 		     struct tcpip_protocol *tcpip,
204 204
 		     struct sockaddr_tcpip *st_dest,
205
+		     struct net_device *netdev,
205 206
 		     uint16_t *trans_csum ) {
206 207
 	struct sockaddr_in6 *dest = ( struct sockaddr_in6* ) st_dest;
207 208
 	struct in6_addr next_hop;
208 209
 	struct ipv6_miniroute *miniroute;
209
-	struct net_device *netdev = NULL;
210 210
 	uint8_t ll_dest_buf[MAX_LL_ADDR_LEN];
211 211
 	const uint8_t *ll_dest = ll_dest_buf;
212 212
 	int rc;

+ 4
- 2
src/net/tcp.c View File

@@ -309,7 +309,8 @@ static int tcp_senddata_conn ( struct tcp_connection *conn, int force_send ) {
309 309
 	DBGC ( conn, "\n" );
310 310
 
311 311
 	/* Transmit packet */
312
-	return tcpip_tx ( pkb, &tcp_protocol, &conn->peer, &tcphdr->csum );
312
+	return tcpip_tx ( pkb, &tcp_protocol, &conn->peer,
313
+			  NULL, &tcphdr->csum );
313 314
 }
314 315
 
315 316
 /**
@@ -465,7 +466,8 @@ static int tcp_send_reset ( struct tcp_connection *conn,
465 466
 	DBGC ( conn, "\n" );
466 467
 
467 468
 	/* Transmit packet */
468
-	return tcpip_tx ( pkb, &tcp_protocol, &conn->peer, &tcphdr->csum );
469
+	return tcpip_tx ( pkb, &tcp_protocol, &conn->peer,
470
+			  NULL, &tcphdr->csum );
469 471
 }
470 472
 
471 473
 /**

+ 4
- 2
src/net/tcpip.c View File

@@ -65,11 +65,13 @@ int tcpip_rx ( struct pk_buff *pkb, uint8_t tcpip_proto,
65 65
  * @v pkb		Packet buffer
66 66
  * @v tcpip_protocol	Transport-layer protocol
67 67
  * @v st_dest		Destination address
68
+ * @v netdev		Network device (or NULL to route automatically)
68 69
  * @v trans_csum	Transport-layer checksum to complete, or NULL
69 70
  * @ret rc		Return status code
70 71
  */
71 72
 int tcpip_tx ( struct pk_buff *pkb, struct tcpip_protocol *tcpip_protocol,
72
-	       struct sockaddr_tcpip *st_dest, uint16_t *trans_csum ) {
73
+	       struct sockaddr_tcpip *st_dest, struct net_device *netdev,
74
+	       uint16_t *trans_csum ) {
73 75
 	struct tcpip_net_protocol *tcpip_net;
74 76
 
75 77
 	/* Hand off packet to the appropriate network-layer protocol */
@@ -78,7 +80,7 @@ int tcpip_tx ( struct pk_buff *pkb, struct tcpip_protocol *tcpip_protocol,
78 80
 		if ( tcpip_net->sa_family == st_dest->st_family ) {
79 81
 			DBG ( "TCP/IP sending %s packet\n", tcpip_net->name );
80 82
 			return tcpip_net->tx ( pkb, tcpip_protocol, st_dest,
81
-					       trans_csum );
83
+					       netdev, trans_csum );
82 84
 		}
83 85
 	}
84 86
 	

+ 1
- 1
src/net/udp.c View File

@@ -162,7 +162,7 @@ int udp_sendto ( struct udp_connection *conn, struct sockaddr_tcpip *peer,
162 162
 	       ntohs ( udphdr->len ) );
163 163
 
164 164
 	/* Send it to the next layer for processing */
165
-	return tcpip_tx ( pkb, &udp_protocol, peer, &udphdr->chksum );
165
+	return tcpip_tx ( pkb, &udp_protocol, peer, NULL, &udphdr->chksum );
166 166
 }
167 167
 
168 168
 /**

Loading…
Cancel
Save