Changes in uspace/srv/net/inetsrv/inet_link.c [4a5a18be:1f97352] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/inetsrv/inet_link.c
r4a5a18be r1f97352 43 43 #include <stdlib.h> 44 44 #include <str.h> 45 45 #include <net/socket_codes.h> 46 46 #include "addrobj.h" 47 47 #include "inetsrv.h" … … 49 49 #include "pdu.h" 50 50 51 static int inet_link_open(service_id_t sid); 52 static int inet_iplink_recv(iplink_t *ilink, iplink_sdu_t *sdu); 51 static bool first_link = true; 52 static bool first_link6 = true; 53 54 static FIBRIL_MUTEX_INITIALIZE(ip_ident_lock); 55 static uint16_t ip_ident = 0; 56 57 static int inet_link_open(service_id_t); 58 static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, uint16_t); 53 59 54 60 static iplink_ev_ops_t inet_iplink_ev_ops = { … … 59 65 static FIBRIL_MUTEX_INITIALIZE(inet_discovery_lock); 60 66 61 static int inet_iplink_recv(iplink_t *iplink, iplink_sdu_t *sdu) 62 { 67 static addr128_t link_local_node_ip = 68 {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xfe, 0, 0, 0}; 69 70 static void inet_link_local_node_ip(addr48_t mac_addr, 71 addr128_t ip_addr) 72 { 73 memcpy(ip_addr, link_local_node_ip, 16); 74 75 ip_addr[8] = mac_addr[0] ^ 0x02; 76 ip_addr[9] = mac_addr[1]; 77 ip_addr[10] = mac_addr[2]; 78 ip_addr[13] = mac_addr[3]; 79 ip_addr[14] = mac_addr[4]; 80 ip_addr[15] = mac_addr[5]; 81 } 82 83 static int inet_iplink_recv(iplink_t *iplink, iplink_recv_sdu_t *sdu, uint16_t af) 84 { 85 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_recv()"); 86 87 int rc; 63 88 inet_packet_t packet; 64 int rc; 65 66 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_recv()"); 67 rc = inet_pdu_decode(sdu->data, sdu->size, &packet); 89 90 switch (af) { 91 case AF_INET: 92 rc = inet_pdu_decode(sdu->data, sdu->size, &packet); 93 break; 94 case AF_INET6: 95 rc = inet_pdu_decode6(sdu->data, sdu->size, &packet); 96 break; 97 default: 98 log_msg(LOG_DEFAULT, LVL_DEBUG, "invalid address family"); 99 return EINVAL; 100 } 101 68 102 if (rc != EOK) { 69 103 log_msg(LOG_DEFAULT, LVL_DEBUG, "failed decoding PDU"); 70 104 return rc; 71 105 } 72 106 73 107 log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet()"); 74 108 rc = inet_recv_packet(&packet); 75 109 log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet -> %d", rc); 76 110 free(packet.data); 77 111 78 112 return rc; 79 113 } … … 147 181 if (ilink->svc_name != NULL) 148 182 free(ilink->svc_name); 183 149 184 free(ilink); 150 185 } … … 153 188 { 154 189 inet_link_t *ilink; 155 i plink_addr_t iaddr;190 inet_addr_t iaddr; 156 191 int rc; 157 192 … … 189 224 goto error; 190 225 } 226 227 /* 228 * Get the MAC address of the link. If the link has a MAC 229 * address, we assume that it supports NDP. 230 */ 231 rc = iplink_get_mac48(ilink->iplink, &ilink->mac); 232 ilink->mac_valid = (rc == EOK); 191 233 192 234 log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name); 193 235 list_append(&ilink->link_list, &inet_link_list); 194 236 195 inet_addrobj_t *addr; 196 197 static int first = 1; 198 /* XXX For testing: set static IP address 10.0.2.15/24 */ 199 addr = inet_addrobj_new(); 200 if (first) { 201 addr->naddr.ipv4 = (127 << 24) + (0 << 16) + (0 << 8) + 1; 202 first = 0; 237 inet_addrobj_t *addr = NULL; 238 239 if (first_link) { 240 addr = inet_addrobj_new(); 241 242 inet_naddr(&addr->naddr, 127, 0, 0, 1, 24); 243 first_link = false; 203 244 } else { 204 addr->naddr.ipv4 = (10 << 24) + (0 << 16) + (2 << 8) + 15; 205 } 206 addr->naddr.bits = 24; 207 addr->ilink = ilink; 208 addr->name = str_dup("v4a"); 209 rc = inet_addrobj_add(addr); 210 if (rc != EOK) { 211 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link."); 212 inet_addrobj_delete(addr); 213 /* XXX Roll back */ 214 return rc; 215 } 216 217 iaddr.ipv4 = addr->naddr.ipv4; 218 rc = iplink_addr_add(ilink->iplink, &iaddr); 219 if (rc != EOK) { 220 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link."); 221 inet_addrobj_remove(addr); 222 inet_addrobj_delete(addr); 223 /* XXX Roll back */ 224 return rc; 225 } 226 245 /* 246 * FIXME 247 * Setting static IPv4 address for testing purposes: 248 * 10.0.2.15/24 249 */ 250 addr = inet_addrobj_new(); 251 252 inet_naddr(&addr->naddr, 10, 0, 2, 15, 24); 253 } 254 255 if (addr != NULL) { 256 addr->ilink = ilink; 257 addr->name = str_dup("v4a"); 258 259 rc = inet_addrobj_add(addr); 260 if (rc == EOK) { 261 inet_naddr_addr(&addr->naddr, &iaddr); 262 rc = iplink_addr_add(ilink->iplink, &iaddr); 263 if (rc != EOK) { 264 log_msg(LOG_DEFAULT, LVL_ERROR, 265 "Failed setting IPv4 address on internet link."); 266 inet_addrobj_remove(addr); 267 inet_addrobj_delete(addr); 268 } 269 } else { 270 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv4 address."); 271 inet_addrobj_delete(addr); 272 } 273 } 274 275 inet_addrobj_t *addr6 = NULL; 276 277 if (first_link6) { 278 addr6 = inet_addrobj_new(); 279 280 inet_naddr6(&addr6->naddr, 0, 0, 0, 0, 0, 0, 0, 1, 128); 281 first_link6 = false; 282 } else if (ilink->mac_valid) { 283 addr6 = inet_addrobj_new(); 284 285 addr128_t link_local; 286 inet_link_local_node_ip(ilink->mac, link_local); 287 288 inet_naddr_set6(link_local, 64, &addr6->naddr); 289 } 290 291 if (addr6 != NULL) { 292 addr6->ilink = ilink; 293 addr6->name = str_dup("v6a"); 294 295 rc = inet_addrobj_add(addr6); 296 if (rc == EOK) { 297 inet_naddr_addr(&addr6->naddr, &iaddr); 298 rc = iplink_addr_add(ilink->iplink, &iaddr); 299 if (rc != EOK) { 300 log_msg(LOG_DEFAULT, LVL_ERROR, 301 "Failed setting IPv6 address on internet link."); 302 inet_addrobj_remove(addr6); 303 inet_addrobj_delete(addr6); 304 } 305 } else { 306 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv6 address."); 307 inet_addrobj_delete(addr6); 308 } 309 } 310 227 311 return EOK; 228 312 229 313 error: 230 314 if (ilink->iplink != NULL) 231 315 iplink_close(ilink->iplink); 316 232 317 inet_link_delete(ilink); 233 318 return rc; … … 253 338 } 254 339 255 /** Send datagram over Internet link */ 256 int inet_link_send_dgram(inet_link_t *ilink, inet_addr_t *lsrc, 257 inet_addr_t *ldest, inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df) 258 { 259 iplink_sdu_t sdu; 260 inet_packet_t packet; 261 int rc; 262 size_t offs, roffs; 263 340 /** Send IPv4 datagram over Internet link 341 * 342 * @param ilink Internet link 343 * @param lsrc Source IPv4 address 344 * @param ldest Destination IPv4 address 345 * @param dgram IPv4 datagram body 346 * @param proto Protocol 347 * @param ttl Time-to-live 348 * @param df Do-not-Fragment flag 349 * 350 * @return EOK on success 351 * @return ENOMEM when not enough memory to create the datagram 352 * @return ENOTSUP if networking mode is not supported 353 * 354 */ 355 int inet_link_send_dgram(inet_link_t *ilink, addr32_t lsrc, addr32_t ldest, 356 inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df) 357 { 358 addr32_t src_v4; 359 uint16_t src_af = inet_addr_get(&dgram->src, &src_v4, NULL); 360 if (src_af != AF_INET) 361 return EINVAL; 362 363 addr32_t dest_v4; 364 uint16_t dest_af = inet_addr_get(&dgram->dest, &dest_v4, NULL); 365 if (dest_af != AF_INET) 366 return EINVAL; 367 264 368 /* 265 369 * Fill packet structure. Fragmentation is performed by 266 370 * inet_pdu_encode(). 267 371 */ 372 373 iplink_sdu_t sdu; 374 375 sdu.src = lsrc; 376 sdu.dest = ldest; 377 378 inet_packet_t packet; 379 268 380 packet.src = dgram->src; 269 381 packet.dest = dgram->dest; … … 271 383 packet.proto = proto; 272 384 packet.ttl = ttl; 385 386 /* Allocate identifier */ 387 fibril_mutex_lock(&ip_ident_lock); 388 packet.ident = ++ip_ident; 389 fibril_mutex_unlock(&ip_ident_lock); 390 273 391 packet.df = df; 274 392 packet.data = dgram->data; 275 393 packet.size = dgram->size; 276 277 sdu.lsrc.ipv4 = lsrc->ipv4; 278 sdu.ldest.ipv4 = ldest->ipv4; 279 280 offs = 0; 394 395 int rc; 396 size_t offs = 0; 397 281 398 do { 282 399 /* Encode one fragment */ 283 rc = inet_pdu_encode(&packet, offs, ilink->def_mtu, &sdu.data, 284 &sdu.size, &roffs); 400 401 size_t roffs; 402 rc = inet_pdu_encode(&packet, src_v4, dest_v4, offs, ilink->def_mtu, 403 &sdu.data, &sdu.size, &roffs); 285 404 if (rc != EOK) 286 405 return rc; 287 406 288 407 /* Send the PDU */ 289 408 rc = iplink_send(ilink->iplink, &sdu); 409 290 410 free(sdu.data); 291 292 411 offs = roffs; 293 412 } while (offs < packet.size); 294 413 414 return rc; 415 } 416 417 /** Send IPv6 datagram over Internet link 418 * 419 * @param ilink Internet link 420 * @param ldest Destination MAC address 421 * @param dgram IPv6 datagram body 422 * @param proto Next header 423 * @param ttl Hop limit 424 * @param df Do-not-Fragment flag (unused) 425 * 426 * @return EOK on success 427 * @return ENOMEM when not enough memory to create the datagram 428 * 429 */ 430 int inet_link_send_dgram6(inet_link_t *ilink, addr48_t ldest, 431 inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df) 432 { 433 addr128_t src_v6; 434 uint16_t src_af = inet_addr_get(&dgram->src, NULL, &src_v6); 435 if (src_af != AF_INET6) 436 return EINVAL; 437 438 addr128_t dest_v6; 439 uint16_t dest_af = inet_addr_get(&dgram->dest, NULL, &dest_v6); 440 if (dest_af != AF_INET6) 441 return EINVAL; 442 443 iplink_sdu6_t sdu6; 444 addr48(ldest, sdu6.dest); 445 446 /* 447 * Fill packet structure. Fragmentation is performed by 448 * inet_pdu_encode6(). 449 */ 450 451 inet_packet_t packet; 452 453 packet.src = dgram->src; 454 packet.dest = dgram->dest; 455 packet.tos = dgram->tos; 456 packet.proto = proto; 457 packet.ttl = ttl; 458 459 /* Allocate identifier */ 460 fibril_mutex_lock(&ip_ident_lock); 461 packet.ident = ++ip_ident; 462 fibril_mutex_unlock(&ip_ident_lock); 463 464 packet.df = df; 465 packet.data = dgram->data; 466 packet.size = dgram->size; 467 468 int rc; 469 size_t offs = 0; 470 471 do { 472 /* Encode one fragment */ 473 474 size_t roffs; 475 rc = inet_pdu_encode6(&packet, src_v6, dest_v6, offs, ilink->def_mtu, 476 &sdu6.data, &sdu6.size, &roffs); 477 if (rc != EOK) 478 return rc; 479 480 /* Send the PDU */ 481 rc = iplink_send6(ilink->iplink, &sdu6); 482 483 free(sdu6.data); 484 offs = roffs; 485 } while (offs < packet.size); 486 295 487 return rc; 296 488 }
Note:
See TracChangeset
for help on using the changeset viewer.