ip_mroute.c (b72bec6c) | ip_mroute.c (77c03cb2) |
---|---|
1/* $OpenBSD: ip_mroute.c,v 1.94 2016/12/13 09:22:18 rzalamena Exp $ */ | 1/* $OpenBSD: ip_mroute.c,v 1.95 2016/12/19 09:22:24 rzalamena Exp $ */ |
2/* $NetBSD: ip_mroute.c,v 1.85 2004/04/26 01:31:57 matt Exp $ */ 3 4/* 5 * Copyright (c) 1989 Stephen Deering 6 * Copyright (c) 1992, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by --- 87 unchanged lines hidden (view full) --- 97 if ((m) && ((m)->m_flags & M_EXT || (m)->m_len < (len))) \ 98 (m) = m_pullup((m), (len)); \ 99 } while (/*CONSTCOND*/ 0) 100 101/* 102 * Globals. All but ip_mrouter and ip_mrtproto could be static, 103 * except for netstat or debugging purposes. 104 */ | 2/* $NetBSD: ip_mroute.c,v 1.85 2004/04/26 01:31:57 matt Exp $ */ 3 4/* 5 * Copyright (c) 1989 Stephen Deering 6 * Copyright (c) 1992, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by --- 87 unchanged lines hidden (view full) --- 97 if ((m) && ((m)->m_flags & M_EXT || (m)->m_len < (len))) \ 98 (m) = m_pullup((m), (len)); \ 99 } while (/*CONSTCOND*/ 0) 100 101/* 102 * Globals. All but ip_mrouter and ip_mrtproto could be static, 103 * except for netstat or debugging purposes. 104 */ |
105struct socket *ip_mrouter = NULL; | 105struct socket *ip_mrouter[RT_TABLEID_MAX]; |
106int ip_mrtproto = IGMP_DVMRP; /* for netstat only */ 107 108#define NO_RTE_FOUND 0x1 109#define RTE_FOUND 0x2 110 | 106int ip_mrtproto = IGMP_DVMRP; /* for netstat only */ 107 108#define NO_RTE_FOUND 0x1 109#define RTE_FOUND 0x2 110 |
111u_int32_t _mfchash(struct in_addr, struct in_addr); | 111u_int32_t _mfchash(unsigned int, struct in_addr, struct in_addr); |
112 | 112 |
113#define MFCHASH(a, g) _mfchash((a), (g)) 114LIST_HEAD(mfchashhdr, mfc) *mfchashtbl; 115u_long mfchash; 116SIPHASH_KEY mfchashkey; | 113#define MFCHASH(r, a, g) _mfchash((r), (a), (g)) 114LIST_HEAD(mfchashhdr, mfc) *mfchashtbl[RT_TABLEID_MAX]; 115u_long mfchash[RT_TABLEID_MAX]; 116SIPHASH_KEY mfchashkey[RT_TABLEID_MAX]; |
117 | 117 |
118u_char nexpire[MFCTBLSIZ]; | 118u_char nexpire[RT_TABLEID_MAX][MFCTBLSIZ]; |
119struct vif viftable[MAXVIFS]; 120struct mrtstat mrtstat; 121 122#define VIFI_INVALID ((vifi_t) -1) 123 124#define EXPIRE_TIMEOUT 250 /* 4x / second */ 125#define UPCALL_EXPIRE 6 /* number of timeouts */ 126struct timeout expire_upcalls_ch; 127 | 119struct vif viftable[MAXVIFS]; 120struct mrtstat mrtstat; 121 122#define VIFI_INVALID ((vifi_t) -1) 123 124#define EXPIRE_TIMEOUT 250 /* 4x / second */ 125#define UPCALL_EXPIRE 6 /* number of timeouts */ 126struct timeout expire_upcalls_ch; 127 |
128int get_sg_cnt(struct sioc_sg_req *); | 128int get_sg_cnt(unsigned int, struct sioc_sg_req *); |
129int get_vif_cnt(struct sioc_vif_req *); 130int get_vif_ctl(struct vifctl *); 131int ip_mrouter_init(struct socket *, struct mbuf *); 132int get_version(struct mbuf *); 133int add_vif(struct socket *, struct mbuf *); 134int del_vif(struct mbuf *); 135void update_mfc_params(struct mfc *, struct mfcctl2 *); 136void init_mfc_params(struct mfc *, struct mfcctl2 *); 137void expire_mfc(struct mfc *); | 129int get_vif_cnt(struct sioc_vif_req *); 130int get_vif_ctl(struct vifctl *); 131int ip_mrouter_init(struct socket *, struct mbuf *); 132int get_version(struct mbuf *); 133int add_vif(struct socket *, struct mbuf *); 134int del_vif(struct mbuf *); 135void update_mfc_params(struct mfc *, struct mfcctl2 *); 136void init_mfc_params(struct mfc *, struct mfcctl2 *); 137void expire_mfc(struct mfc *); |
138int add_mfc(struct mbuf *); 139int del_mfc(struct mbuf *); 140int set_api_config(struct mbuf *); /* chose API capabilities */ | 138int add_mfc(struct socket *, struct mbuf *); 139int del_mfc(struct socket *, struct mbuf *); 140int set_api_config(struct socket *, struct mbuf *); /* chose API capabilities */ |
141int get_api_support(struct mbuf *); 142int get_api_config(struct mbuf *); 143int socket_send(struct socket *, struct mbuf *, 144 struct sockaddr_in *); 145void expire_upcalls(void *); 146int ip_mdq(struct mbuf *, struct ifnet *, struct mfc *); 147void phyint_send(struct ip *, struct vif *, struct mbuf *); 148void send_packet(struct vif *, struct mbuf *); --- 81 unchanged lines hidden (view full) --- 230 231/* 232 * Find a route for a given origin IP address and Multicast group address 233 * Type of service parameter to be added in the future!!! 234 * Statistics are updated by the caller if needed 235 * (mrtstat.mrts_mfc_lookups and mrtstat.mrts_mfc_misses) 236 */ 237static struct mfc * | 141int get_api_support(struct mbuf *); 142int get_api_config(struct mbuf *); 143int socket_send(struct socket *, struct mbuf *, 144 struct sockaddr_in *); 145void expire_upcalls(void *); 146int ip_mdq(struct mbuf *, struct ifnet *, struct mfc *); 147void phyint_send(struct ip *, struct vif *, struct mbuf *); 148void send_packet(struct vif *, struct mbuf *); --- 81 unchanged lines hidden (view full) --- 230 231/* 232 * Find a route for a given origin IP address and Multicast group address 233 * Type of service parameter to be added in the future!!! 234 * Statistics are updated by the caller if needed 235 * (mrtstat.mrts_mfc_lookups and mrtstat.mrts_mfc_misses) 236 */ 237static struct mfc * |
238mfc_find(struct in_addr *o, struct in_addr *g) | 238mfc_find(unsigned int rtableid, struct in_addr *o, struct in_addr *g) |
239{ 240 struct mfc *rt; 241 u_int32_t hash; 242 | 239{ 240 struct mfc *rt; 241 u_int32_t hash; 242 |
243 hash = MFCHASH(*o, *g); 244 LIST_FOREACH(rt, &mfchashtbl[hash], mfc_hash) { | 243 if (mfchashtbl[rtableid] == NULL) 244 return (NULL); 245 246 hash = MFCHASH(rtableid, *o, *g); 247 LIST_FOREACH(rt, &mfchashtbl[rtableid][hash], mfc_hash) { |
245 if (in_hosteq(rt->mfc_origin, *o) && 246 in_hosteq(rt->mfc_mcastgrp, *g) && 247 (rt->mfc_stall == NULL)) 248 break; 249 } 250 251 return (rt); 252} --- 22 unchanged lines hidden (view full) --- 275} while (/*CONSTCOND*/ 0) 276 277/* 278 * Handle MRT setsockopt commands to modify the multicast routing tables. 279 */ 280int 281ip_mrouter_set(struct socket *so, int optname, struct mbuf **mp) 282{ | 248 if (in_hosteq(rt->mfc_origin, *o) && 249 in_hosteq(rt->mfc_mcastgrp, *g) && 250 (rt->mfc_stall == NULL)) 251 break; 252 } 253 254 return (rt); 255} --- 22 unchanged lines hidden (view full) --- 278} while (/*CONSTCOND*/ 0) 279 280/* 281 * Handle MRT setsockopt commands to modify the multicast routing tables. 282 */ 283int 284ip_mrouter_set(struct socket *so, int optname, struct mbuf **mp) 285{ |
286 struct inpcb *inp = sotoinpcb(so); |
|
283 int error; 284 | 287 int error; 288 |
285 if (optname != MRT_INIT && so != ip_mrouter) | 289 if (optname != MRT_INIT && 290 so != ip_mrouter[inp->inp_rtableid]) |
286 error = ENOPROTOOPT; 287 else 288 switch (optname) { 289 case MRT_INIT: 290 error = ip_mrouter_init(so, *mp); 291 break; 292 case MRT_DONE: | 291 error = ENOPROTOOPT; 292 else 293 switch (optname) { 294 case MRT_INIT: 295 error = ip_mrouter_init(so, *mp); 296 break; 297 case MRT_DONE: |
293 error = ip_mrouter_done(); | 298 error = ip_mrouter_done(so); |
294 break; 295 case MRT_ADD_VIF: 296 error = add_vif(so, *mp); 297 break; 298 case MRT_DEL_VIF: 299 error = del_vif(*mp); 300 break; 301 case MRT_ADD_MFC: | 299 break; 300 case MRT_ADD_VIF: 301 error = add_vif(so, *mp); 302 break; 303 case MRT_DEL_VIF: 304 error = del_vif(*mp); 305 break; 306 case MRT_ADD_MFC: |
302 error = add_mfc(*mp); | 307 error = add_mfc(so, *mp); |
303 break; 304 case MRT_DEL_MFC: | 308 break; 309 case MRT_DEL_MFC: |
305 error = del_mfc(*mp); | 310 error = del_mfc(so, *mp); |
306 break; 307#ifdef PIM 308 case MRT_ASSERT: 309 error = set_assert(*mp); 310 break; 311#endif 312 case MRT_API_CONFIG: | 311 break; 312#ifdef PIM 313 case MRT_ASSERT: 314 error = set_assert(*mp); 315 break; 316#endif 317 case MRT_API_CONFIG: |
313 error = set_api_config(*mp); | 318 error = set_api_config(so, *mp); |
314 break; 315 default: 316 error = ENOPROTOOPT; 317 break; 318 } 319 320 m_free(*mp); 321 return (error); 322} 323 324/* 325 * Handle MRT getsockopt commands 326 */ 327int 328ip_mrouter_get(struct socket *so, int optname, struct mbuf **mp) 329{ | 319 break; 320 default: 321 error = ENOPROTOOPT; 322 break; 323 } 324 325 m_free(*mp); 326 return (error); 327} 328 329/* 330 * Handle MRT getsockopt commands 331 */ 332int 333ip_mrouter_get(struct socket *so, int optname, struct mbuf **mp) 334{ |
335 struct inpcb *inp = sotoinpcb(so); |
|
330 int error; 331 | 336 int error; 337 |
332 if (so != ip_mrouter) | 338 if (so != ip_mrouter[inp->inp_rtableid]) |
333 error = ENOPROTOOPT; 334 else { 335 *mp = m_get(M_WAIT, MT_SOOPTS); 336 337 switch (optname) { 338 case MRT_VERSION: 339 error = get_version(*mp); 340 break; --- 21 unchanged lines hidden (view full) --- 362} 363 364/* 365 * Handle ioctl commands to obtain information from the cache 366 */ 367int 368mrt_ioctl(struct socket *so, u_long cmd, caddr_t data) 369{ | 339 error = ENOPROTOOPT; 340 else { 341 *mp = m_get(M_WAIT, MT_SOOPTS); 342 343 switch (optname) { 344 case MRT_VERSION: 345 error = get_version(*mp); 346 break; --- 21 unchanged lines hidden (view full) --- 368} 369 370/* 371 * Handle ioctl commands to obtain information from the cache 372 */ 373int 374mrt_ioctl(struct socket *so, u_long cmd, caddr_t data) 375{ |
376 struct inpcb *inp = sotoinpcb(so); |
|
370 int error; 371 | 377 int error; 378 |
372 if (so != ip_mrouter) | 379 if (so != ip_mrouter[inp->inp_rtableid]) |
373 error = EINVAL; 374 else 375 switch (cmd) { 376 case SIOCGETVIFCNT: 377 error = get_vif_cnt((struct sioc_vif_req *)data); 378 break; 379 case SIOCGETSGCNT: | 380 error = EINVAL; 381 else 382 switch (cmd) { 383 case SIOCGETVIFCNT: 384 error = get_vif_cnt((struct sioc_vif_req *)data); 385 break; 386 case SIOCGETSGCNT: |
380 error = get_sg_cnt((struct sioc_sg_req *)data); | 387 error = get_sg_cnt(inp->inp_rtableid, 388 (struct sioc_sg_req *)data); |
381 break; 382 default: 383 error = ENOTTY; 384 break; 385 } 386 387 return (error); 388} 389 390/* 391 * returns the packet, byte, rpf-failure count for the source group provided 392 */ 393int | 389 break; 390 default: 391 error = ENOTTY; 392 break; 393 } 394 395 return (error); 396} 397 398/* 399 * returns the packet, byte, rpf-failure count for the source group provided 400 */ 401int |
394get_sg_cnt(struct sioc_sg_req *req) | 402get_sg_cnt(unsigned int rtableid, struct sioc_sg_req *req) |
395{ 396 int s; 397 struct mfc *rt; 398 399 s = splsoftnet(); | 403{ 404 int s; 405 struct mfc *rt; 406 407 s = splsoftnet(); |
400 rt = mfc_find(&req->src, &req->grp); | 408 rt = mfc_find(rtableid, &req->src, &req->grp); |
401 if (rt == NULL) { 402 splx(s); 403 req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff; 404 return (EADDRNOTAVAIL); 405 } 406 req->pktcnt = rt->mfc_pkt_cnt; 407 req->bytecnt = rt->mfc_byte_cnt; 408 req->wrong_if = rt->mfc_wrong_if; --- 68 unchanged lines hidden (view full) --- 477} 478 479int 480mrt_sysctl_mfc(void *oldp, size_t *oldlenp) 481{ 482 caddr_t where = oldp; 483 size_t needed, given; 484 u_long i; | 409 if (rt == NULL) { 410 splx(s); 411 req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff; 412 return (EADDRNOTAVAIL); 413 } 414 req->pktcnt = rt->mfc_pkt_cnt; 415 req->bytecnt = rt->mfc_byte_cnt; 416 req->wrong_if = rt->mfc_wrong_if; --- 68 unchanged lines hidden (view full) --- 485} 486 487int 488mrt_sysctl_mfc(void *oldp, size_t *oldlenp) 489{ 490 caddr_t where = oldp; 491 size_t needed, given; 492 u_long i; |
493 unsigned int rtableid; |
|
485 struct mfc *m; 486 struct mfcinfo minfo; 487 488 given = *oldlenp; 489 needed = 0; | 494 struct mfc *m; 495 struct mfcinfo minfo; 496 497 given = *oldlenp; 498 needed = 0; |
490 for (i = 0; mfchashtbl && i < MFCTBLSIZ; ++i) { 491 LIST_FOREACH(m, &mfchashtbl[i], mfc_hash) { 492 minfo.mfc_origin = m->mfc_origin; 493 minfo.mfc_mcastgrp = m->mfc_mcastgrp; 494 minfo.mfc_parent = m->mfc_parent; 495 minfo.mfc_pkt_cnt = m->mfc_pkt_cnt; 496 minfo.mfc_byte_cnt = m->mfc_byte_cnt; 497 memcpy(minfo.mfc_ttls, m->mfc_ttls, MAXVIFS); | 499 for (rtableid = 0; rtableid < RT_TABLEID_MAX; rtableid++) { 500 if (mfchashtbl[rtableid] == NULL) 501 continue; |
498 | 502 |
499 needed += sizeof(minfo); 500 if (where && needed <= given) { 501 int error; | 503 for (i = 0; i < MFCTBLSIZ; ++i) { 504 LIST_FOREACH(m, &mfchashtbl[rtableid][i], mfc_hash) { 505 minfo.mfc_origin = m->mfc_origin; 506 minfo.mfc_mcastgrp = m->mfc_mcastgrp; 507 minfo.mfc_parent = m->mfc_parent; 508 minfo.mfc_pkt_cnt = m->mfc_pkt_cnt; 509 minfo.mfc_byte_cnt = m->mfc_byte_cnt; 510 memcpy(minfo.mfc_ttls, m->mfc_ttls, MAXVIFS); |
502 | 511 |
503 error = copyout(&minfo, where, sizeof(minfo)); 504 if (error) 505 return (error); 506 where += sizeof(minfo); | 512 needed += sizeof(minfo); 513 if (where && needed <= given) { 514 int error; 515 516 error = copyout(&minfo, where, 517 sizeof(minfo)); 518 if (error) 519 return (error); 520 where += sizeof(minfo); 521 } |
507 } 508 } 509 } 510 if (where) { 511 *oldlenp = needed; 512 if (given < needed) 513 return (ENOMEM); 514 } else 515 *oldlenp = (11 * needed) / 10; 516 517 return (0); 518} 519 520/* 521 * Enable multicast routing 522 */ 523int 524ip_mrouter_init(struct socket *so, struct mbuf *m) 525{ | 522 } 523 } 524 } 525 if (where) { 526 *oldlenp = needed; 527 if (given < needed) 528 return (ENOMEM); 529 } else 530 *oldlenp = (11 * needed) / 10; 531 532 return (0); 533} 534 535/* 536 * Enable multicast routing 537 */ 538int 539ip_mrouter_init(struct socket *so, struct mbuf *m) 540{ |
541 struct inpcb *inp = sotoinpcb(so); 542 unsigned int rtableid = inp->inp_rtableid; |
|
526 int *v; 527 528 if (so->so_type != SOCK_RAW || 529 so->so_proto->pr_protocol != IPPROTO_IGMP) 530 return (EOPNOTSUPP); 531 532 if (m == NULL || m->m_len < sizeof(int)) 533 return (EINVAL); 534 535 v = mtod(m, int *); 536 if (*v != 1) 537 return (EINVAL); 538 | 543 int *v; 544 545 if (so->so_type != SOCK_RAW || 546 so->so_proto->pr_protocol != IPPROTO_IGMP) 547 return (EOPNOTSUPP); 548 549 if (m == NULL || m->m_len < sizeof(int)) 550 return (EINVAL); 551 552 v = mtod(m, int *); 553 if (*v != 1) 554 return (EINVAL); 555 |
539 if (ip_mrouter != NULL) | 556 if (ip_mrouter[rtableid] != NULL) |
540 return (EADDRINUSE); 541 | 557 return (EADDRINUSE); 558 |
542 ip_mrouter = so; | 559 ip_mrouter[rtableid] = so; |
543 | 560 |
544 mfchashtbl = hashinit(MFCTBLSIZ, M_MRTABLE, M_WAITOK, &mfchash); 545 arc4random_buf(&mfchashkey, sizeof(mfchashkey)); 546 memset(nexpire, 0, sizeof(nexpire)); | 561 mfchashtbl[rtableid] = 562 hashinit(MFCTBLSIZ, M_MRTABLE, M_WAITOK, &mfchash[rtableid]); 563 arc4random_buf(&mfchashkey[rtableid], sizeof(mfchashkey[rtableid])); 564 memset(nexpire[rtableid], 0, sizeof(nexpire[rtableid])); |
547 548#ifdef PIM 549 pim_assert = 0; 550#endif 551 552 timeout_set(&expire_upcalls_ch, expire_upcalls, NULL); 553 timeout_add_msec(&expire_upcalls_ch, EXPIRE_TIMEOUT); 554 555 return (0); 556} 557 558u_int32_t | 565 566#ifdef PIM 567 pim_assert = 0; 568#endif 569 570 timeout_set(&expire_upcalls_ch, expire_upcalls, NULL); 571 timeout_add_msec(&expire_upcalls_ch, EXPIRE_TIMEOUT); 572 573 return (0); 574} 575 576u_int32_t |
559_mfchash(struct in_addr o, struct in_addr g) | 577_mfchash(unsigned int rtableid, struct in_addr o, struct in_addr g) |
560{ 561 SIPHASH_CTX ctx; 562 | 578{ 579 SIPHASH_CTX ctx; 580 |
563 SipHash24_Init(&ctx, &mfchashkey); | 581 SipHash24_Init(&ctx, &mfchashkey[rtableid]); |
564 SipHash24_Update(&ctx, &o.s_addr, sizeof(o.s_addr)); 565 SipHash24_Update(&ctx, &g.s_addr, sizeof(g.s_addr)); 566 | 582 SipHash24_Update(&ctx, &o.s_addr, sizeof(o.s_addr)); 583 SipHash24_Update(&ctx, &g.s_addr, sizeof(g.s_addr)); 584 |
567 return (SipHash24_End(&ctx) & mfchash); | 585 return (SipHash24_End(&ctx) & mfchash[rtableid]); |
568} 569 570/* 571 * Disable multicast routing 572 */ 573int | 586} 587 588/* 589 * Disable multicast routing 590 */ 591int |
574ip_mrouter_done(void) | 592ip_mrouter_done(struct socket *so) |
575{ | 593{ |
594 struct inpcb *inp = sotoinpcb(so); |
|
576 vifi_t vifi; 577 struct vif *vifp; 578 int i; 579 int s; | 595 vifi_t vifi; 596 struct vif *vifp; 597 int i; 598 int s; |
599 unsigned int rtableid = inp->inp_rtableid; |
|
580 581 s = splsoftnet(); 582 583 /* Clear out all the vifs currently in use. */ 584 for (vifi = 0; vifi < numvifs; vifi++) { 585 vifp = &viftable[vifi]; 586 if (!in_nullhost(vifp->v_lcl_addr)) 587 reset_vif(vifp); --- 9 unchanged lines hidden (view full) --- 597 timeout_del(&expire_upcalls_ch); 598 599 /* 600 * Free all multicast forwarding cache entries. 601 */ 602 for (i = 0; i < MFCTBLSIZ; i++) { 603 struct mfc *rt, *nrt; 604 | 600 601 s = splsoftnet(); 602 603 /* Clear out all the vifs currently in use. */ 604 for (vifi = 0; vifi < numvifs; vifi++) { 605 vifp = &viftable[vifi]; 606 if (!in_nullhost(vifp->v_lcl_addr)) 607 reset_vif(vifp); --- 9 unchanged lines hidden (view full) --- 617 timeout_del(&expire_upcalls_ch); 618 619 /* 620 * Free all multicast forwarding cache entries. 621 */ 622 for (i = 0; i < MFCTBLSIZ; i++) { 623 struct mfc *rt, *nrt; 624 |
605 for (rt = LIST_FIRST(&mfchashtbl[i]); rt; rt = nrt) { | 625 for (rt = LIST_FIRST(&mfchashtbl[rtableid][i]); rt; rt = nrt) { |
606 nrt = LIST_NEXT(rt, mfc_hash); 607 608 expire_mfc(rt); 609 } 610 } 611 | 626 nrt = LIST_NEXT(rt, mfc_hash); 627 628 expire_mfc(rt); 629 } 630 } 631 |
612 memset(nexpire, 0, sizeof(nexpire)); 613 hashfree(mfchashtbl, MFCTBLSIZ, M_MRTABLE); 614 mfchashtbl = NULL; | 632 memset(nexpire[rtableid], 0, sizeof(nexpire[rtableid])); 633 hashfree(mfchashtbl[rtableid], MFCTBLSIZ, M_MRTABLE); 634 mfchashtbl[rtableid] = NULL; |
615 | 635 |
616 ip_mrouter = NULL; | 636 ip_mrouter[rtableid] = NULL; |
617 618 splx(s); 619 620 return (0); 621} 622 623void 624ip_mrouter_detach(struct ifnet *ifp) --- 7 unchanged lines hidden (view full) --- 632 for (vifi = 0; vifi < numvifs; vifi++) { 633 vifp = &viftable[vifi]; 634 if (vifp->v_ifp == ifp) 635 reset_vif(vifp); 636 } 637 for (i = 0; i < MFCTBLSIZ; i++) { 638 if (nexpire[i] == 0) 639 continue; | 637 638 splx(s); 639 640 return (0); 641} 642 643void 644ip_mrouter_detach(struct ifnet *ifp) --- 7 unchanged lines hidden (view full) --- 652 for (vifi = 0; vifi < numvifs; vifi++) { 653 vifp = &viftable[vifi]; 654 if (vifp->v_ifp == ifp) 655 reset_vif(vifp); 656 } 657 for (i = 0; i < MFCTBLSIZ; i++) { 658 if (nexpire[i] == 0) 659 continue; |
640 LIST_FOREACH(rt, &mfchashtbl[i], mfc_hash) { | 660 LIST_FOREACH(rt, &mfchashtbl[ifp->if_rdomain][i], mfc_hash) { |
641 for (rte = rt->mfc_stall; rte; rte = rte->next) { 642 if (rte->ifp == ifp) 643 rte->ifp = NULL; 644 } 645 } 646 } 647} 648 --- 37 unchanged lines hidden (view full) --- 686 return (0); 687} 688#endif 689 690/* 691 * Configure API capabilities 692 */ 693int | 661 for (rte = rt->mfc_stall; rte; rte = rte->next) { 662 if (rte->ifp == ifp) 663 rte->ifp = NULL; 664 } 665 } 666 } 667} 668 --- 37 unchanged lines hidden (view full) --- 706 return (0); 707} 708#endif 709 710/* 711 * Configure API capabilities 712 */ 713int |
694set_api_config(struct mbuf *m) | 714set_api_config(struct socket *so, struct mbuf *m) |
695{ | 715{ |
716 struct inpcb *inp = sotoinpcb(so); |
|
696 int i; 697 u_int32_t *apival; | 717 int i; 718 u_int32_t *apival; |
719 unsigned int rtableid = inp->inp_rtableid; |
|
698 699 if (m == NULL || m->m_len < sizeof(u_int32_t)) 700 return (EINVAL); 701 702 apival = mtod(m, u_int32_t *); 703 704 /* 705 * We can set the API capabilities only if it is the first operation --- 8 unchanged lines hidden (view full) --- 714 } 715#ifdef PIM 716 if (pim_assert) { 717 *apival = 0; 718 return (EPERM); 719 } 720#endif 721 for (i = 0; i < MFCTBLSIZ; i++) { | 720 721 if (m == NULL || m->m_len < sizeof(u_int32_t)) 722 return (EINVAL); 723 724 apival = mtod(m, u_int32_t *); 725 726 /* 727 * We can set the API capabilities only if it is the first operation --- 8 unchanged lines hidden (view full) --- 736 } 737#ifdef PIM 738 if (pim_assert) { 739 *apival = 0; 740 return (EPERM); 741 } 742#endif 743 for (i = 0; i < MFCTBLSIZ; i++) { |
722 if (LIST_FIRST(&mfchashtbl[i]) != NULL) { | 744 if (mfchashtbl[rtableid] == NULL) 745 break; 746 747 if (LIST_FIRST(&mfchashtbl[rtableid][i]) != NULL) { |
723 *apival = 0; 724 return (EPERM); 725 } 726 } 727 728 mrt_api_config = *apival & mrt_api_support; 729 *apival = mrt_api_config; 730 --- 201 unchanged lines hidden (view full) --- 932 933void 934vif_delete(struct ifnet *ifp) 935{ 936 int i; 937 struct vif *vifp; 938 struct mfc *rt; 939 struct rtdetq *rte; | 748 *apival = 0; 749 return (EPERM); 750 } 751 } 752 753 mrt_api_config = *apival & mrt_api_support; 754 *apival = mrt_api_config; 755 --- 201 unchanged lines hidden (view full) --- 957 958void 959vif_delete(struct ifnet *ifp) 960{ 961 int i; 962 struct vif *vifp; 963 struct mfc *rt; 964 struct rtdetq *rte; |
965 unsigned int rtableid = ifp->if_rdomain; |
|
940 941 for (i = 0; i < numvifs; i++) { 942 vifp = &viftable[i]; 943 if (vifp->v_ifp == ifp) 944 memset(vifp, 0, sizeof(*vifp)); 945 } 946 947 for (i = numvifs; i > 0; i--) 948 if (!in_nullhost(viftable[i - 1].v_lcl_addr)) 949 break; 950 numvifs = i; 951 | 966 967 for (i = 0; i < numvifs; i++) { 968 vifp = &viftable[i]; 969 if (vifp->v_ifp == ifp) 970 memset(vifp, 0, sizeof(*vifp)); 971 } 972 973 for (i = numvifs; i > 0; i--) 974 if (!in_nullhost(viftable[i - 1].v_lcl_addr)) 975 break; 976 numvifs = i; 977 |
978 if (ip_mrouter[rtableid] == NULL) 979 return; 980 |
|
952 for (i = 0; i < MFCTBLSIZ; i++) { | 981 for (i = 0; i < MFCTBLSIZ; i++) { |
953 if (nexpire[i] == 0) | 982 if (nexpire[rtableid][i] == 0) |
954 continue; | 983 continue; |
955 LIST_FOREACH(rt, &mfchashtbl[i], mfc_hash) { | 984 985 LIST_FOREACH(rt, &mfchashtbl[rtableid][i], mfc_hash) { |
956 for (rte = rt->mfc_stall; rte; rte = rte->next) { 957 if (rte->ifp == ifp) 958 rte->ifp = NULL; 959 } 960 } 961 } 962} 963 --- 50 unchanged lines hidden (view full) --- 1014 LIST_REMOVE(rt, mfc_hash); 1015 free(rt, M_MRTABLE, 0); 1016} 1017 1018/* 1019 * Add an mfc entry 1020 */ 1021int | 986 for (rte = rt->mfc_stall; rte; rte = rte->next) { 987 if (rte->ifp == ifp) 988 rte->ifp = NULL; 989 } 990 } 991 } 992} 993 --- 50 unchanged lines hidden (view full) --- 1044 LIST_REMOVE(rt, mfc_hash); 1045 free(rt, M_MRTABLE, 0); 1046} 1047 1048/* 1049 * Add an mfc entry 1050 */ 1051int |
1022add_mfc(struct mbuf *m) | 1052add_mfc(struct socket *so, struct mbuf *m) |
1023{ | 1053{ |
1054 struct inpcb *inp = sotoinpcb(so); |
|
1024 struct mfcctl2 mfcctl2; 1025 struct mfcctl2 *mfccp; 1026 struct mfc *rt; 1027 u_int32_t hash = 0; 1028 struct rtdetq *rte, *nrte; 1029 u_short nstl; 1030 int s; 1031 int mfcctl_size = sizeof(struct mfcctl); | 1055 struct mfcctl2 mfcctl2; 1056 struct mfcctl2 *mfccp; 1057 struct mfc *rt; 1058 u_int32_t hash = 0; 1059 struct rtdetq *rte, *nrte; 1060 u_short nstl; 1061 int s; 1062 int mfcctl_size = sizeof(struct mfcctl); |
1063 unsigned int rtableid = inp->inp_rtableid; |
|
1032 1033 if (mrt_api_config & MRT_API_FLAGS_ALL) 1034 mfcctl_size = sizeof(struct mfcctl2); 1035 1036 if (m == NULL || m->m_len < mfcctl_size) 1037 return (EINVAL); 1038 1039 /* --- 6 unchanged lines hidden (view full) --- 1046 struct mfcctl *mp = mtod(m, struct mfcctl *); 1047 bcopy(mp, (caddr_t)&mfcctl2, sizeof(*mp)); 1048 memset((caddr_t)&mfcctl2 + sizeof(struct mfcctl), 0, 1049 sizeof(mfcctl2) - sizeof(struct mfcctl)); 1050 } 1051 mfccp = &mfcctl2; 1052 1053 s = splsoftnet(); | 1064 1065 if (mrt_api_config & MRT_API_FLAGS_ALL) 1066 mfcctl_size = sizeof(struct mfcctl2); 1067 1068 if (m == NULL || m->m_len < mfcctl_size) 1069 return (EINVAL); 1070 1071 /* --- 6 unchanged lines hidden (view full) --- 1078 struct mfcctl *mp = mtod(m, struct mfcctl *); 1079 bcopy(mp, (caddr_t)&mfcctl2, sizeof(*mp)); 1080 memset((caddr_t)&mfcctl2 + sizeof(struct mfcctl), 0, 1081 sizeof(mfcctl2) - sizeof(struct mfcctl)); 1082 } 1083 mfccp = &mfcctl2; 1084 1085 s = splsoftnet(); |
1054 rt = mfc_find(&mfccp->mfcc_origin, &mfccp->mfcc_mcastgrp); | 1086 /* No hash table allocated for this. */ 1087 if (mfchashtbl[rtableid] == NULL) { 1088 splx(s); 1089 return (0); 1090 } |
1055 | 1091 |
1092 rt = mfc_find(rtableid, &mfccp->mfcc_origin, &mfccp->mfcc_mcastgrp); 1093 |
|
1056 /* If an entry already exists, just update the fields */ 1057 if (rt) { 1058 update_mfc_params(rt, mfccp); 1059 splx(s); 1060 return (0); 1061 } 1062 1063 /* 1064 * Find the entry for which the upcall was made and update 1065 */ 1066 nstl = 0; | 1094 /* If an entry already exists, just update the fields */ 1095 if (rt) { 1096 update_mfc_params(rt, mfccp); 1097 splx(s); 1098 return (0); 1099 } 1100 1101 /* 1102 * Find the entry for which the upcall was made and update 1103 */ 1104 nstl = 0; |
1067 hash = MFCHASH(mfccp->mfcc_origin, mfccp->mfcc_mcastgrp); 1068 LIST_FOREACH(rt, &mfchashtbl[hash], mfc_hash) { | 1105 hash = MFCHASH(rtableid, mfccp->mfcc_origin, mfccp->mfcc_mcastgrp); 1106 LIST_FOREACH(rt, &mfchashtbl[rtableid][hash], mfc_hash) { |
1069 if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) && 1070 in_hosteq(rt->mfc_mcastgrp, mfccp->mfcc_mcastgrp) && 1071 rt->mfc_stall != NULL) { 1072 if (nstl++) { 1073 log(LOG_ERR, "add_mfc %s o %x g %x " 1074 "p %x dbx %p\n", 1075 "multiple kernel entries", 1076 ntohl(mfccp->mfcc_origin.s_addr), 1077 ntohl(mfccp->mfcc_mcastgrp.s_addr), 1078 mfccp->mfcc_parent, rt->mfc_stall); 1079 } 1080 1081 rte = rt->mfc_stall; 1082 init_mfc_params(rt, mfccp); 1083 rt->mfc_stall = NULL; 1084 1085 rt->mfc_expire = 0; /* Don't clean this guy up */ | 1107 if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) && 1108 in_hosteq(rt->mfc_mcastgrp, mfccp->mfcc_mcastgrp) && 1109 rt->mfc_stall != NULL) { 1110 if (nstl++) { 1111 log(LOG_ERR, "add_mfc %s o %x g %x " 1112 "p %x dbx %p\n", 1113 "multiple kernel entries", 1114 ntohl(mfccp->mfcc_origin.s_addr), 1115 ntohl(mfccp->mfcc_mcastgrp.s_addr), 1116 mfccp->mfcc_parent, rt->mfc_stall); 1117 } 1118 1119 rte = rt->mfc_stall; 1120 init_mfc_params(rt, mfccp); 1121 rt->mfc_stall = NULL; 1122 1123 rt->mfc_expire = 0; /* Don't clean this guy up */ |
1086 nexpire[hash]--; | 1124 nexpire[rtableid][hash]--; |
1087 1088 /* free packets Qed at the end of this entry */ 1089 for (; rte != NULL; rte = nrte) { 1090 nrte = rte->next; 1091 if (rte->ifp) { 1092 ip_mdq(rte->m, rte->ifp, rt); 1093 } 1094 m_freem(rte->m); --- 4 unchanged lines hidden (view full) --- 1099 1100 /* 1101 * It is possible that an entry is being inserted without an upcall 1102 */ 1103 if (nstl == 0) { 1104 /* 1105 * No mfc; make a new one 1106 */ | 1125 1126 /* free packets Qed at the end of this entry */ 1127 for (; rte != NULL; rte = nrte) { 1128 nrte = rte->next; 1129 if (rte->ifp) { 1130 ip_mdq(rte->m, rte->ifp, rt); 1131 } 1132 m_freem(rte->m); --- 4 unchanged lines hidden (view full) --- 1137 1138 /* 1139 * It is possible that an entry is being inserted without an upcall 1140 */ 1141 if (nstl == 0) { 1142 /* 1143 * No mfc; make a new one 1144 */ |
1107 LIST_FOREACH(rt, &mfchashtbl[hash], mfc_hash) { | 1145 LIST_FOREACH(rt, &mfchashtbl[rtableid][hash], mfc_hash) { |
1108 if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) && 1109 in_hosteq(rt->mfc_mcastgrp, mfccp->mfcc_mcastgrp)) { 1110 init_mfc_params(rt, mfccp); 1111 if (rt->mfc_expire) | 1146 if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) && 1147 in_hosteq(rt->mfc_mcastgrp, mfccp->mfcc_mcastgrp)) { 1148 init_mfc_params(rt, mfccp); 1149 if (rt->mfc_expire) |
1112 nexpire[hash]--; | 1150 nexpire[rtableid][hash]--; |
1113 rt->mfc_expire = 0; 1114 break; /* XXX */ 1115 } 1116 } 1117 if (rt == NULL) { /* no upcall, so make a new entry */ 1118 rt = malloc(sizeof(*rt), M_MRTABLE, M_NOWAIT); 1119 if (rt == NULL) { 1120 splx(s); 1121 return (ENOBUFS); 1122 } 1123 1124 init_mfc_params(rt, mfccp); 1125 rt->mfc_expire = 0; 1126 rt->mfc_stall = NULL; 1127 1128 /* insert new entry at head of hash chain */ | 1151 rt->mfc_expire = 0; 1152 break; /* XXX */ 1153 } 1154 } 1155 if (rt == NULL) { /* no upcall, so make a new entry */ 1156 rt = malloc(sizeof(*rt), M_MRTABLE, M_NOWAIT); 1157 if (rt == NULL) { 1158 splx(s); 1159 return (ENOBUFS); 1160 } 1161 1162 init_mfc_params(rt, mfccp); 1163 rt->mfc_expire = 0; 1164 rt->mfc_stall = NULL; 1165 1166 /* insert new entry at head of hash chain */ |
1129 LIST_INSERT_HEAD(&mfchashtbl[hash], rt, mfc_hash); | 1167 LIST_INSERT_HEAD(&mfchashtbl[rtableid][hash], rt, mfc_hash); |
1130 } 1131 } 1132 1133 splx(s); 1134 return (0); 1135} 1136 1137/* 1138 * Delete an mfc entry 1139 */ 1140int | 1168 } 1169 } 1170 1171 splx(s); 1172 return (0); 1173} 1174 1175/* 1176 * Delete an mfc entry 1177 */ 1178int |
1141del_mfc(struct mbuf *m) | 1179del_mfc(struct socket *so, struct mbuf *m) |
1142{ | 1180{ |
1181 struct inpcb *inp = sotoinpcb(so); |
|
1143 struct mfcctl2 mfcctl2; 1144 struct mfcctl2 *mfccp; 1145 struct mfc *rt; 1146 int s; 1147 int mfcctl_size = sizeof(struct mfcctl); 1148 struct mfcctl *mp = mtod(m, struct mfcctl *); | 1182 struct mfcctl2 mfcctl2; 1183 struct mfcctl2 *mfccp; 1184 struct mfc *rt; 1185 int s; 1186 int mfcctl_size = sizeof(struct mfcctl); 1187 struct mfcctl *mp = mtod(m, struct mfcctl *); |
1188 unsigned int rtableid = inp->inp_rtableid; |
|
1149 1150 /* 1151 * XXX: for deleting MFC entries the information in entries 1152 * of size "struct mfcctl" is sufficient. 1153 */ 1154 1155 if (m == NULL || m->m_len < mfcctl_size) 1156 return (EINVAL); 1157 1158 bcopy(mp, (caddr_t)&mfcctl2, sizeof(*mp)); 1159 memset((caddr_t)&mfcctl2 + sizeof(struct mfcctl), 0, 1160 sizeof(mfcctl2) - sizeof(struct mfcctl)); 1161 1162 mfccp = &mfcctl2; 1163 1164 s = splsoftnet(); 1165 | 1189 1190 /* 1191 * XXX: for deleting MFC entries the information in entries 1192 * of size "struct mfcctl" is sufficient. 1193 */ 1194 1195 if (m == NULL || m->m_len < mfcctl_size) 1196 return (EINVAL); 1197 1198 bcopy(mp, (caddr_t)&mfcctl2, sizeof(*mp)); 1199 memset((caddr_t)&mfcctl2 + sizeof(struct mfcctl), 0, 1200 sizeof(mfcctl2) - sizeof(struct mfcctl)); 1201 1202 mfccp = &mfcctl2; 1203 1204 s = splsoftnet(); 1205 |
1166 rt = mfc_find(&mfccp->mfcc_origin, &mfccp->mfcc_mcastgrp); | 1206 rt = mfc_find(rtableid, &mfccp->mfcc_origin, &mfccp->mfcc_mcastgrp); |
1167 if (rt == NULL) { 1168 splx(s); 1169 return (EADDRNOTAVAIL); 1170 } 1171 1172 LIST_REMOVE(rt, mfc_hash); 1173 free(rt, M_MRTABLE, 0); 1174 --- 32 unchanged lines hidden (view full) --- 1207ip_mforward(struct mbuf *m, struct ifnet *ifp) 1208{ 1209 struct ip *ip = mtod(m, struct ip *); 1210 struct mfc *rt; 1211 static int srctun = 0; 1212 struct mbuf *mm; 1213 int s; 1214 vifi_t vifi; | 1207 if (rt == NULL) { 1208 splx(s); 1209 return (EADDRNOTAVAIL); 1210 } 1211 1212 LIST_REMOVE(rt, mfc_hash); 1213 free(rt, M_MRTABLE, 0); 1214 --- 32 unchanged lines hidden (view full) --- 1247ip_mforward(struct mbuf *m, struct ifnet *ifp) 1248{ 1249 struct ip *ip = mtod(m, struct ip *); 1250 struct mfc *rt; 1251 static int srctun = 0; 1252 struct mbuf *mm; 1253 int s; 1254 vifi_t vifi; |
1255 unsigned int rtableid = ifp->if_rdomain; |
|
1215 1216 if (ip->ip_hl < (IP_HDR_LEN + TUNNEL_LEN) >> 2 || 1217 ((u_char *)(ip + 1))[1] != IPOPT_LSRR) { 1218 /* 1219 * Packet arrived via a physical interface or 1220 * an encapsulated tunnel or a register_vif. 1221 */ 1222 } else { --- 15 unchanged lines hidden (view full) --- 1238 if (ip->ip_ttl <= 1 || IN_LOCAL_GROUP(ip->ip_dst.s_addr)) 1239 return (0); 1240 1241 /* 1242 * Determine forwarding vifs from the forwarding cache table 1243 */ 1244 s = splsoftnet(); 1245 ++mrtstat.mrts_mfc_lookups; | 1256 1257 if (ip->ip_hl < (IP_HDR_LEN + TUNNEL_LEN) >> 2 || 1258 ((u_char *)(ip + 1))[1] != IPOPT_LSRR) { 1259 /* 1260 * Packet arrived via a physical interface or 1261 * an encapsulated tunnel or a register_vif. 1262 */ 1263 } else { --- 15 unchanged lines hidden (view full) --- 1279 if (ip->ip_ttl <= 1 || IN_LOCAL_GROUP(ip->ip_dst.s_addr)) 1280 return (0); 1281 1282 /* 1283 * Determine forwarding vifs from the forwarding cache table 1284 */ 1285 s = splsoftnet(); 1286 ++mrtstat.mrts_mfc_lookups; |
1246 rt = mfc_find(&ip->ip_src, &ip->ip_dst); | 1287 rt = mfc_find(rtableid, &ip->ip_src, &ip->ip_dst); |
1247 1248 /* Entry exists, so forward if necessary */ 1249 if (rt != NULL) { 1250 splx(s); 1251 return (ip_mdq(m, ifp, rt)); 1252 } else { 1253 /* 1254 * If we don't have a route for packet's origin, --- 22 unchanged lines hidden (view full) --- 1277 M_PULLUP(mb0, hlen); 1278 if (mb0 == NULL) { 1279 free(rte, M_MRTABLE, 0); 1280 splx(s); 1281 return (ENOBUFS); 1282 } 1283 1284 /* is there an upcall waiting for this flow? */ | 1288 1289 /* Entry exists, so forward if necessary */ 1290 if (rt != NULL) { 1291 splx(s); 1292 return (ip_mdq(m, ifp, rt)); 1293 } else { 1294 /* 1295 * If we don't have a route for packet's origin, --- 22 unchanged lines hidden (view full) --- 1318 M_PULLUP(mb0, hlen); 1319 if (mb0 == NULL) { 1320 free(rte, M_MRTABLE, 0); 1321 splx(s); 1322 return (ENOBUFS); 1323 } 1324 1325 /* is there an upcall waiting for this flow? */ |
1285 hash = MFCHASH(ip->ip_src, ip->ip_dst); 1286 LIST_FOREACH(rt, &mfchashtbl[hash], mfc_hash) { | 1326 hash = MFCHASH(rtableid, ip->ip_src, ip->ip_dst); 1327 LIST_FOREACH(rt, &mfchashtbl[rtableid][hash], mfc_hash) { |
1287 if (in_hosteq(ip->ip_src, rt->mfc_origin) && 1288 in_hosteq(ip->ip_dst, rt->mfc_mcastgrp) && 1289 rt->mfc_stall != NULL) 1290 break; 1291 } 1292 1293 if (rt == NULL) { 1294 int i; --- 31 unchanged lines hidden (view full) --- 1326 im = mtod(mm, struct igmpmsg *); 1327 im->im_msgtype = IGMPMSG_NOCACHE; 1328 im->im_mbz = 0; 1329 im->im_vif = vifi; 1330 1331 mrtstat.mrts_upcalls++; 1332 1333 sin.sin_addr = ip->ip_src; | 1328 if (in_hosteq(ip->ip_src, rt->mfc_origin) && 1329 in_hosteq(ip->ip_dst, rt->mfc_mcastgrp) && 1330 rt->mfc_stall != NULL) 1331 break; 1332 } 1333 1334 if (rt == NULL) { 1335 int i; --- 31 unchanged lines hidden (view full) --- 1367 im = mtod(mm, struct igmpmsg *); 1368 im->im_msgtype = IGMPMSG_NOCACHE; 1369 im->im_mbz = 0; 1370 im->im_vif = vifi; 1371 1372 mrtstat.mrts_upcalls++; 1373 1374 sin.sin_addr = ip->ip_src; |
1334 if (socket_send(ip_mrouter, mm, &sin) < 0) { | 1375 if (socket_send(ip_mrouter[rtableid], mm, &sin) < 0) { |
1335 log(LOG_WARNING, "ip_mforward: ip_mrouter " 1336 "socket queue full\n"); 1337 ++mrtstat.mrts_upq_sockfull; 1338 fail1: 1339 free(rt, M_MRTABLE, 0); 1340 fail: 1341 free(rte, M_MRTABLE, 0); 1342 m_freem(mb0); 1343 splx(s); 1344 return (ENOBUFS); 1345 } 1346 1347 /* insert new entry at head of hash chain */ 1348 rt->mfc_origin = ip->ip_src; 1349 rt->mfc_mcastgrp = ip->ip_dst; 1350 rt->mfc_pkt_cnt = 0; 1351 rt->mfc_byte_cnt = 0; 1352 rt->mfc_wrong_if = 0; 1353 rt->mfc_expire = UPCALL_EXPIRE; | 1376 log(LOG_WARNING, "ip_mforward: ip_mrouter " 1377 "socket queue full\n"); 1378 ++mrtstat.mrts_upq_sockfull; 1379 fail1: 1380 free(rt, M_MRTABLE, 0); 1381 fail: 1382 free(rte, M_MRTABLE, 0); 1383 m_freem(mb0); 1384 splx(s); 1385 return (ENOBUFS); 1386 } 1387 1388 /* insert new entry at head of hash chain */ 1389 rt->mfc_origin = ip->ip_src; 1390 rt->mfc_mcastgrp = ip->ip_dst; 1391 rt->mfc_pkt_cnt = 0; 1392 rt->mfc_byte_cnt = 0; 1393 rt->mfc_wrong_if = 0; 1394 rt->mfc_expire = UPCALL_EXPIRE; |
1354 nexpire[hash]++; | 1395 nexpire[rtableid][hash]++; |
1355 for (i = 0; i < numvifs; i++) { 1356 rt->mfc_ttls[i] = 0; 1357 rt->mfc_flags[i] = 0; 1358 } 1359 rt->mfc_parent = -1; 1360 1361 /* clear the RP address */ 1362 rt->mfc_rp = zeroin_addr; 1363 1364 /* link into table */ | 1396 for (i = 0; i < numvifs; i++) { 1397 rt->mfc_ttls[i] = 0; 1398 rt->mfc_flags[i] = 0; 1399 } 1400 rt->mfc_parent = -1; 1401 1402 /* clear the RP address */ 1403 rt->mfc_rp = zeroin_addr; 1404 1405 /* link into table */ |
1365 LIST_INSERT_HEAD(&mfchashtbl[hash], rt, mfc_hash); | 1406 LIST_INSERT_HEAD(&mfchashtbl[rtableid][hash], rt, mfc_hash); |
1366 /* Add this entry to the end of the queue */ 1367 rt->mfc_stall = rte; 1368 } else { 1369 /* determine if q has overflowed */ 1370 struct rtdetq **p; 1371 int npkts = 0; 1372 1373 /* --- 27 unchanged lines hidden (view full) --- 1401 1402 1403/*ARGSUSED*/ 1404void 1405expire_upcalls(void *v) 1406{ 1407 int i; 1408 int s; | 1407 /* Add this entry to the end of the queue */ 1408 rt->mfc_stall = rte; 1409 } else { 1410 /* determine if q has overflowed */ 1411 struct rtdetq **p; 1412 int npkts = 0; 1413 1414 /* --- 27 unchanged lines hidden (view full) --- 1442 1443 1444/*ARGSUSED*/ 1445void 1446expire_upcalls(void *v) 1447{ 1448 int i; 1449 int s; |
1450 unsigned int rtableid; |
|
1409 1410 s = splsoftnet(); 1411 1412 for (i = 0; i < MFCTBLSIZ; i++) { 1413 struct mfc *rt, *nrt; 1414 | 1451 1452 s = splsoftnet(); 1453 1454 for (i = 0; i < MFCTBLSIZ; i++) { 1455 struct mfc *rt, *nrt; 1456 |
1415 if (nexpire[i] == 0) | 1457 if (nexpire[rtableid][i] == 0) |
1416 continue; 1417 | 1458 continue; 1459 |
1418 for (rt = LIST_FIRST(&mfchashtbl[i]); rt; rt = nrt) { 1419 nrt = LIST_NEXT(rt, mfc_hash); 1420 1421 if (rt->mfc_expire == 0 || --rt->mfc_expire > 0) | 1460 for (rtableid = 0; rtableid < RT_TABLEID_MAX; rtableid++) { 1461 if (mfchashtbl[rtableid] == NULL) |
1422 continue; | 1462 continue; |
1423 nexpire[i]--; | |
1424 | 1463 |
1425 ++mrtstat.mrts_cache_cleanups; 1426 expire_mfc(rt); | 1464 for (rt = LIST_FIRST(&mfchashtbl[rtableid][i]); rt; 1465 rt = nrt) { 1466 nrt = LIST_NEXT(rt, mfc_hash); 1467 1468 if (rt->mfc_expire == 0 || --rt->mfc_expire > 0) 1469 continue; 1470 nexpire[rtableid][i]--; 1471 1472 ++mrtstat.mrts_cache_cleanups; 1473 expire_mfc(rt); 1474 } |
1427 } 1428 } 1429 1430 splx(s); 1431 timeout_add_msec(&expire_upcalls_ch, EXPIRE_TIMEOUT); 1432} 1433 1434/* --- 65 unchanged lines hidden (view full) --- 1500 im = mtod(mm, struct igmpmsg *); 1501 im->im_msgtype = IGMPMSG_WRONGVIF; 1502 im->im_mbz = 0; 1503 im->im_vif = vifi; 1504 1505 mrtstat.mrts_upcalls++; 1506 1507 sin.sin_addr = im->im_src; | 1475 } 1476 } 1477 1478 splx(s); 1479 timeout_add_msec(&expire_upcalls_ch, EXPIRE_TIMEOUT); 1480} 1481 1482/* --- 65 unchanged lines hidden (view full) --- 1548 im = mtod(mm, struct igmpmsg *); 1549 im->im_msgtype = IGMPMSG_WRONGVIF; 1550 im->im_mbz = 0; 1551 im->im_vif = vifi; 1552 1553 mrtstat.mrts_upcalls++; 1554 1555 sin.sin_addr = im->im_src; |
1508 if (socket_send(ip_mrouter, mm, &sin) < 0) { | 1556 if (socket_send(ip_mrouter[rtableid], mm, 1557 &sin) < 0) { |
1509 log(LOG_WARNING, "ip_mforward: " 1510 "ip_mrouter socket queue full\n"); 1511 ++mrtstat.mrts_upq_sockfull; 1512 return (ENOBUFS); 1513 } 1514 } 1515 } 1516#endif --- 182 unchanged lines hidden (view full) --- 1699 im->im_vif = vifp - viftable; 1700 im->im_src = ip->ip_src; 1701 im->im_dst = ip->ip_dst; 1702 1703 k_igmpsrc.sin_addr = ip->ip_src; 1704 1705 mrtstat.mrts_upcalls++; 1706 | 1558 log(LOG_WARNING, "ip_mforward: " 1559 "ip_mrouter socket queue full\n"); 1560 ++mrtstat.mrts_upq_sockfull; 1561 return (ENOBUFS); 1562 } 1563 } 1564 } 1565#endif --- 182 unchanged lines hidden (view full) --- 1748 im->im_vif = vifp - viftable; 1749 im->im_src = ip->ip_src; 1750 im->im_dst = ip->ip_dst; 1751 1752 k_igmpsrc.sin_addr = ip->ip_src; 1753 1754 mrtstat.mrts_upcalls++; 1755 |
1707 if (socket_send(ip_mrouter, mb_first, &k_igmpsrc) < 0) { | 1756 if (socket_send(ip_mrouter[rtableid], mb_first, &k_igmpsrc) < 0) { |
1708 ++mrtstat.mrts_upq_sockfull; 1709 return (ENOBUFS); 1710 } 1711 1712 /* Keep statistics */ 1713 pimstat.pims_snd_registers_msgs++; 1714 pimstat.pims_snd_registers_bytes += len; 1715 --- 310 unchanged lines hidden --- | 1757 ++mrtstat.mrts_upq_sockfull; 1758 return (ENOBUFS); 1759 } 1760 1761 /* Keep statistics */ 1762 pimstat.pims_snd_registers_msgs++; 1763 pimstat.pims_snd_registers_bytes += len; 1764 --- 310 unchanged lines hidden --- |