ip_mroute.c revision 9266
11573Srgrimes/* 21573Srgrimes * IP multicast forwarding procedures 31573Srgrimes * 41573Srgrimes * Written by David Waitzman, BBN Labs, August 1988. 51573Srgrimes * Modified by Steve Deering, Stanford, February 1989. 61573Srgrimes * Modified by Mark J. Steiglitz, Stanford, May, 1991 71573Srgrimes * Modified by Van Jacobson, LBL, January 1993 81573Srgrimes * Modified by Ajit Thyagarajan, PARC, August 1993 91573Srgrimes * Modified by Bill Fenner, PARC, April 1995 101573Srgrimes * 111573Srgrimes * MROUTING Revision: 3.5 121573Srgrimes */ 131573Srgrimes 141573Srgrimes 151573Srgrimes#include <sys/param.h> 161573Srgrimes#include <sys/systm.h> 171573Srgrimes#include <sys/mbuf.h> 181573Srgrimes#include <sys/socket.h> 191573Srgrimes#include <sys/socketvar.h> 201573Srgrimes#include <sys/protosw.h> 211573Srgrimes#include <sys/errno.h> 221573Srgrimes#include <sys/time.h> 231573Srgrimes#include <sys/kernel.h> 241573Srgrimes#include <sys/ioctl.h> 251573Srgrimes#include <sys/syslog.h> 261573Srgrimes#include <sys/queue.h> 271573Srgrimes#include <net/if.h> 281573Srgrimes#include <net/route.h> 291573Srgrimes#include <netinet/in.h> 301573Srgrimes#include <netinet/in_systm.h> 311573Srgrimes#include <netinet/ip.h> 321573Srgrimes#include <netinet/ip_var.h> 331573Srgrimes#include <netinet/in_pcb.h> 341573Srgrimes#include <netinet/in_var.h> 351573Srgrimes#include <netinet/igmp.h> 361573Srgrimes#include <netinet/igmp_var.h> 371573Srgrimes#include <netinet/ip_mroute.h> 381573Srgrimes#include <netinet/udp.h> 391573Srgrimes 4092986Sobrien#ifndef NTOHL 4192986Sobrien#if BYTE_ORDER != BIG_ENDIAN 421573Srgrimes#define NTOHL(d) ((d) = ntohl((d))) 431573Srgrimes#define NTOHS(d) ((d) = ntohs((u_short)(d))) 44132820Stjr#define HTONL(d) ((d) = htonl((d))) 45121845Stjr#define HTONS(d) ((d) = htons((u_short)(d))) 46129153Stjr#else 471573Srgrimes#define NTOHL(d) 481573Srgrimes#define NTOHS(d) 491573Srgrimes#define HTONL(d) 5061218Sache#define HTONS(d) 51121845Stjr#endif 52121845Stjr#endif 531573Srgrimes 541573Srgrimesextern int rsvp_on; 5557035Sobrien 5657035Sobrien#ifndef MROUTING 5757035Sobrien/* 5857035Sobrien * Dummy routines and globals used when multicast routing is not compiled in. 5957035Sobrien */ 6057035Sobrien 6157035Sobrienstruct socket *ip_mrouter = NULL; 6257035Sobrienu_int ip_mrtproto = 0; 6357035Sobrienstruct mrtstat mrtstat; 6457035Sobrienu_int rsvpdebug = 0; 6557035Sobrien 6657035Sobrienint 6757035Sobrien_ip_mrouter_set(cmd, so, m) 6857035Sobrien int cmd; 6957035Sobrien struct socket *so; 7057035Sobrien struct mbuf *m; 7157035Sobrien{ 7257035Sobrien return(EOPNOTSUPP); 7357035Sobrien} 7457035Sobrien 7557035Sobrienint (*ip_mrouter_set)(int, struct socket *, struct mbuf *) = _ip_mrouter_set; 7657035Sobrien 7757035Sobrien 7857035Sobrienint 7957035Sobrien_ip_mrouter_get(cmd, so, m) 8057035Sobrien int cmd; 8157035Sobrien struct socket *so; 8257035Sobrien struct mbuf **m; 8357035Sobrien{ 8457035Sobrien return(EOPNOTSUPP); 8557035Sobrien} 8657035Sobrien 8757035Sobrienint (*ip_mrouter_get)(int, struct socket *, struct mbuf **) = _ip_mrouter_get; 8857035Sobrien 8957035Sobrienint 9057035Sobrien_ip_mrouter_done() 9157035Sobrien{ 9257035Sobrien return(0); 9357035Sobrien} 9457035Sobrien 9557035Sobrienint (*ip_mrouter_done)(void) = _ip_mrouter_done; 9657035Sobrien 9757035Sobrienint 9857035Sobrien_ip_mforward(ip, ifp, m, imo) 9957035Sobrien struct ip *ip; 10057035Sobrien struct ifnet *ifp; 10157035Sobrien struct mbuf *m; 10257035Sobrien struct ip_moptions *imo; 10357035Sobrien{ 10457035Sobrien return(0); 10557035Sobrien} 10657035Sobrien 10757035Sobrienint (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *, 10857035Sobrien struct ip_moptions *) = _ip_mforward; 10957035Sobrien 11057035Sobrienint 11157035Sobrien_mrt_ioctl(int req, caddr_t data, struct proc *p) 11257035Sobrien{ 11357035Sobrien return EOPNOTSUPP; 11457035Sobrien} 11557035Sobrien 11657035Sobrienint (*mrt_ioctl)(int, caddr_t, struct proc *) = _mrt_ioctl; 11757035Sobrien 11857035Sobrienvoid 11957035Sobrienrsvp_input(m, iphlen) /* XXX must fixup manually */ 12057035Sobrien struct mbuf *m; 12157035Sobrien int iphlen; 12257035Sobrien{ 12357035Sobrien /* Can still get packets with rsvp_on = 0 if there is a local member 12457035Sobrien * of the group to which the RSVP packet is addressed. But in this 12557035Sobrien * case we want to throw the packet away. 12657035Sobrien */ 12757035Sobrien if (!rsvp_on) { 12857035Sobrien m_freem(m); 12957035Sobrien return; 13057035Sobrien } 13157035Sobrien 13257035Sobrien if (ip_rsvpd != NULL) { 13357035Sobrien if (rsvpdebug) 13457035Sobrien printf("rsvp_input: Sending packet up old-style socket\n"); 13557035Sobrien rip_input(m); 13657035Sobrien return; 13757035Sobrien } 13857035Sobrien /* Drop the packet */ 13957035Sobrien m_freem(m); 14057035Sobrien} 14157035Sobrien 14257035Sobrienvoid ipip_input(struct mbuf *m) { /* XXX must fixup manually */ 14357035Sobrien rip_input(m); 14457035Sobrien} 14557035Sobrien 14657035Sobrienint (*legal_vif_num)(int) = 0; 14757035Sobrien 14857035Sobrien/* 14957035Sobrien * This should never be called, since IP_MULTICAST_VIF should fail, but 15057035Sobrien * just in case it does get called, the code a little lower in ip_output 15157035Sobrien * will assign the packet a local address. 15257035Sobrien */ 15357035Sobrienu_long 15457035Sobrien_ip_mcast_src(int vifi) { return INADDR_ANY; } 15557035Sobrienu_long (*ip_mcast_src)(int) = _ip_mcast_src; 15657035Sobrien 15757035Sobrienint 15857035Sobrienip_rsvp_vif_init(so, m) 15957035Sobrien struct socket *so; 16057035Sobrien struct mbuf *m; 16157035Sobrien{ 16257035Sobrien return(EINVAL); 16357035Sobrien} 16457035Sobrien 16557035Sobrienint 16657035Sobrienip_rsvp_vif_done(so, m) 16757035Sobrien struct socket *so; 16857035Sobrien struct mbuf *m; 16957035Sobrien{ 17057035Sobrien return(EINVAL); 17157035Sobrien} 17257035Sobrien 17357035Sobrienvoid 17457035Sobrienip_rsvp_force_done(so) 17557035Sobrien struct socket *so; 17657035Sobrien{ 17757035Sobrien return; 17857035Sobrien} 17957035Sobrien 18057035Sobrien#else /* MROUTING */ 18157035Sobrien 18257035Sobrien#define M_HASCL(m) ((m)->m_flags & M_EXT) 1831573Srgrimes 1841573Srgrimes#define INSIZ sizeof(struct in_addr) 1851573Srgrimes#define same(a1, a2) \ 1861573Srgrimes (bcmp((caddr_t)(a1), (caddr_t)(a2), INSIZ) == 0) 1871573Srgrimes 1881573Srgrimes#define MT_MRTABLE MT_RTABLE /* since nothing else uses it */ 1891573Srgrimes 1901573Srgrimes/* 1911573Srgrimes * Globals. All but ip_mrouter and ip_mrtproto could be static, 1921573Srgrimes * except for netstat or debugging purposes. 1931573Srgrimes */ 1941573Srgrimes#ifndef MROUTE_LKM 1951573Srgrimesstruct socket *ip_mrouter = NULL; 1961573Srgrimesstruct mrtstat mrtstat; 1971573Srgrimes 1981573Srgrimesint ip_mrtproto = IGMP_DVMRP; /* for netstat only */ 1991573Srgrimes#else /* MROUTE_LKM */ 2001573Srgrimesextern struct mrtstat mrtstat; 2011573Srgrimesextern int ip_mrtproto; 2021573Srgrimes#endif 2031573Srgrimes 2041573Srgrimes#define NO_RTE_FOUND 0x1 2051573Srgrimes#define RTE_FOUND 0x2 2061573Srgrimes 2071573Srgrimesstruct mbuf *mfctable[MFCTBLSIZ]; 2081573Srgrimesu_char nexpire[MFCTBLSIZ]; 2091573Srgrimesstruct vif viftable[MAXVIFS]; 2101573Srgrimesu_int mrtdebug = 0; /* debug level */ 2111573Srgrimes#define DEBUG_MFC 0x02 2121573Srgrimes#define DEBUG_FORWARD 0x04 2131573Srgrimes#define DEBUG_EXPIRE 0x08 2141573Srgrimes#define DEBUG_XMIT 0x10 2151573Srgrimesu_int tbfdebug = 0; /* tbf debug level */ 2161573Srgrimesu_int rsvpdebug = 0; /* rsvp debug level */ 2171573Srgrimes 2181573Srgrimes#define EXPIRE_TIMEOUT (hz / 4) /* 4x / second */ 2191573Srgrimes#define UPCALL_EXPIRE 6 /* number of timeouts */ 2201573Srgrimes 2211573Srgrimes/* 2221573Srgrimes * Define the token bucket filter structures 2231573Srgrimes * tbftable -> each vif has one of these for storing info 2241573Srgrimes * qtable -> each interface has an associated queue of pkts 2251573Srgrimes */ 2261573Srgrimes 2271573Srgrimesstruct tbf tbftable[MAXVIFS]; 2281573Srgrimesstruct pkt_queue qtable[MAXVIFS][MAXQSIZE]; 2291573Srgrimes 2301573Srgrimes/* 2311573Srgrimes * 'Interfaces' associated with decapsulator (so we can tell 2321573Srgrimes * packets that went through it from ones that get reflected 2331573Srgrimes * by a broken gateway). These interfaces are never linked into 2341573Srgrimes * the system ifnet list & no routes point to them. I.e., packets 2351573Srgrimes * can't be sent this way. They only exist as a placeholder for 2361573Srgrimes * multicast source verification. 2371573Srgrimes */ 2381573Srgrimesstruct ifnet multicast_decap_if[MAXVIFS]; 2391573Srgrimes 2401573Srgrimes#define ENCAP_TTL 64 2411573Srgrimes#define ENCAP_PROTO IPPROTO_IPIP /* 4 */ 2421573Srgrimes 2431573Srgrimes/* prototype IP hdr for encapsulated packets */ 2441573Srgrimesstruct ip multicast_encap_iphdr = { 2451573Srgrimes#if BYTE_ORDER == LITTLE_ENDIAN 2461573Srgrimes sizeof(struct ip) >> 2, IPVERSION, 2471573Srgrimes#else 2481573Srgrimes IPVERSION, sizeof(struct ip) >> 2, 2491573Srgrimes#endif 2501573Srgrimes 0, /* tos */ 2511573Srgrimes sizeof(struct ip), /* total length */ 2521573Srgrimes 0, /* id */ 2531573Srgrimes 0, /* frag offset */ 2541573Srgrimes ENCAP_TTL, ENCAP_PROTO, 255121845Stjr 0, /* checksum */ 256121845Stjr}; 257128004Stjr 258132497Stjr/* 259132497Stjr * Private variables. 260121845Stjr */ 261121845Stjrstatic vifi_t numvifs = 0; 262132497Stjrstatic void (*encap_oldrawip)() = 0; 263132497Stjrstatic int have_encap_tunnel = 0; 264 265/* 266 * one-back cache used by ipip_input to locate a tunnel's vif 267 * given a datagram's src ip address. 268 */ 269static u_long last_encap_src; 270static struct vif *last_encap_vif; 271 272static int get_sg_cnt(struct sioc_sg_req *); 273static int get_vif_cnt(struct sioc_vif_req *); 274int ip_mrouter_init(struct socket *, struct mbuf *); 275static int add_vif(struct vifctl *); 276static int del_vif(vifi_t *); 277static int add_mfc(struct mfcctl *); 278static int del_mfc(struct mfcctl *); 279static int get_version(struct mbuf *); 280static int get_assert(struct mbuf *); 281static int set_assert(int *); 282static void expire_upcalls(void *); 283static int ip_mdq(struct mbuf *, struct ifnet *, struct mfc *, 284 vifi_t); 285static void phyint_send(struct ip *, struct vif *, struct mbuf *); 286static void encap_send(struct ip *, struct vif *, struct mbuf *); 287static void tbf_control(struct vif *, struct mbuf *, struct ip *, u_long, 288 struct ip_moptions *); 289static void tbf_queue(struct vif *, struct mbuf *, struct ip *, struct ip_moptions *); 290static void tbf_process_q(struct vif *); 291static void tbf_dequeue(struct vif *, int); 292static void tbf_reprocess_q(void *); 293static int tbf_dq_sel(struct vif *, struct ip *); 294static void tbf_send_packet(struct vif *, struct mbuf *, struct ip_moptions *); 295static void tbf_update_tokens(struct vif *); 296static int priority(struct vif *, struct ip *); 297void multiencap_decap(struct mbuf *); 298 299/* 300 * whether or not special PIM assert processing is enabled. 301 */ 302static int pim_assert; 303/* 304 * Rate limit for assert notification messages, in usec 305 */ 306#define ASSERT_MSG_TIME 3000000 307 308/* 309 * Hash function for a source, group entry 310 */ 311#define MFCHASH(a, g) MFCHASHMOD(((a) >> 20) ^ ((a) >> 10) ^ (a) ^ \ 312 ((g) >> 20) ^ ((g) >> 10) ^ (g)) 313 314/* 315 * Find a route for a given origin IP address and Multicast group address 316 * Type of service parameter to be added in the future!!! 317 */ 318 319#define MFCFIND(o, g, rt) { \ 320 register struct mbuf *_mb_rt = mfctable[MFCHASH(o,g)]; \ 321 register struct mfc *_rt = NULL; \ 322 rt = NULL; \ 323 ++mrtstat.mrts_mfc_lookups; \ 324 while (_mb_rt) { \ 325 _rt = mtod(_mb_rt, struct mfc *); \ 326 if ((_rt->mfc_origin.s_addr == o) && \ 327 (_rt->mfc_mcastgrp.s_addr == g) && \ 328 (_mb_rt->m_act == NULL)) { \ 329 rt = _rt; \ 330 break; \ 331 } \ 332 _mb_rt = _mb_rt->m_next; \ 333 } \ 334 if (rt == NULL) { \ 335 ++mrtstat.mrts_mfc_misses; \ 336 } \ 337} 338 339 340/* 341 * Macros to compute elapsed time efficiently 342 * Borrowed from Van Jacobson's scheduling code 343 */ 344#define TV_DELTA(a, b, delta) { \ 345 register int xxs; \ 346 \ 347 delta = (a).tv_usec - (b).tv_usec; \ 348 if ((xxs = (a).tv_sec - (b).tv_sec)) { \ 349 switch (xxs) { \ 350 case 2: \ 351 delta += 1000000; \ 352 /* fall through */ \ 353 case 1: \ 354 delta += 1000000; \ 355 break; \ 356 default: \ 357 delta += (1000000 * xxs); \ 358 } \ 359 } \ 360} 361 362#define TV_LT(a, b) (((a).tv_usec < (b).tv_usec && \ 363 (a).tv_sec <= (b).tv_sec) || (a).tv_sec < (b).tv_sec) 364 365#ifdef UPCALL_TIMING 366u_long upcall_data[51]; 367static void collate(struct timeval *); 368#endif /* UPCALL_TIMING */ 369 370 371/* 372 * Handle MRT setsockopt commands to modify the multicast routing tables. 373 */ 374int 375X_ip_mrouter_set(cmd, so, m) 376 int cmd; 377 struct socket *so; 378 struct mbuf *m; 379{ 380 if (cmd != MRT_INIT && so != ip_mrouter) return EACCES; 381 382 switch (cmd) { 383 case MRT_INIT: return ip_mrouter_init(so, m); 384 case MRT_DONE: return ip_mrouter_done(); 385 case MRT_ADD_VIF: return add_vif (mtod(m, struct vifctl *)); 386 case MRT_DEL_VIF: return del_vif (mtod(m, vifi_t *)); 387 case MRT_ADD_MFC: return add_mfc (mtod(m, struct mfcctl *)); 388 case MRT_DEL_MFC: return del_mfc (mtod(m, struct mfcctl *)); 389 case MRT_ASSERT: return set_assert(mtod(m, int *)); 390 default: return EOPNOTSUPP; 391 } 392} 393 394#ifndef MROUTE_LKM 395int (*ip_mrouter_set)(int, struct socket *, struct mbuf *) = X_ip_mrouter_set; 396#endif 397 398/* 399 * Handle MRT getsockopt commands 400 */ 401int 402X_ip_mrouter_get(cmd, so, m) 403 int cmd; 404 struct socket *so; 405 struct mbuf **m; 406{ 407 struct mbuf *mb; 408 409 if (so != ip_mrouter) return EACCES; 410 411 *m = mb = m_get(M_WAIT, MT_SOOPTS); 412 413 switch (cmd) { 414 case MRT_VERSION: return get_version(mb); 415 case MRT_ASSERT: return get_assert(mb); 416 default: return EOPNOTSUPP; 417 } 418} 419 420#ifndef MROUTE_LKM 421int (*ip_mrouter_get)(int, struct socket *, struct mbuf **) = X_ip_mrouter_get; 422#endif 423 424/* 425 * Handle ioctl commands to obtain information from the cache 426 */ 427int 428X_mrt_ioctl(cmd, data) 429 int cmd; 430 caddr_t data; 431{ 432 int error = 0; 433 434 switch (cmd) { 435 case (SIOCGETVIFCNT): 436 return (get_vif_cnt((struct sioc_vif_req *)data)); 437 break; 438 case (SIOCGETSGCNT): 439 return (get_sg_cnt((struct sioc_sg_req *)data)); 440 break; 441 default: 442 return (EINVAL); 443 break; 444 } 445 return error; 446} 447 448#ifndef MROUTE_LKM 449int (*mrt_ioctl)(int, caddr_t, struct proc *) = X_mrt_ioctl; 450#endif 451 452/* 453 * returns the packet, byte, rpf-failure count for the source group provided 454 */ 455static int 456get_sg_cnt(req) 457 register struct sioc_sg_req *req; 458{ 459 register struct mfc *rt; 460 int s; 461 462 s = splnet(); 463 MFCFIND(req->src.s_addr, req->grp.s_addr, rt); 464 splx(s); 465 if (rt != NULL) { 466 req->pktcnt = rt->mfc_pkt_cnt; 467 req->bytecnt = rt->mfc_byte_cnt; 468 req->wrong_if = rt->mfc_wrong_if; 469 } else 470 req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff; 471 472 return 0; 473} 474 475/* 476 * returns the input and output packet and byte counts on the vif provided 477 */ 478static int 479get_vif_cnt(req) 480 register struct sioc_vif_req *req; 481{ 482 register vifi_t vifi = req->vifi; 483 484 if (vifi >= numvifs) return EINVAL; 485 486 req->icount = viftable[vifi].v_pkt_in; 487 req->ocount = viftable[vifi].v_pkt_out; 488 req->ibytes = viftable[vifi].v_bytes_in; 489 req->obytes = viftable[vifi].v_bytes_out; 490 491 return 0; 492} 493 494/* 495 * Enable multicast routing 496 */ 497int 498ip_mrouter_init(so, m) 499 struct socket *so; 500 struct mbuf *m; 501{ 502 int *v; 503 int i; 504 505 if (mrtdebug) 506 log(LOG_DEBUG,"ip_mrouter_init: so_type = %d, pr_protocol = %d", 507 so->so_type, so->so_proto->pr_protocol); 508 509 if (so->so_type != SOCK_RAW || 510 so->so_proto->pr_protocol != IPPROTO_IGMP) return EOPNOTSUPP; 511 512 if (!m || (m->m_len != sizeof(int *))) 513 return ENOPROTOOPT; 514 515 v = mtod(m, int *); 516 if (*v != 1) 517 return ENOPROTOOPT; 518 519 if (ip_mrouter != NULL) return EADDRINUSE; 520 521 ip_mrouter = so; 522 523 bzero((caddr_t)mfctable, sizeof(mfctable)); 524 bzero((caddr_t)nexpire, sizeof(nexpire)); 525 526 pim_assert = 0; 527 528 timeout(expire_upcalls, (caddr_t)NULL, EXPIRE_TIMEOUT); 529 530 if (mrtdebug) 531 log(LOG_DEBUG, "ip_mrouter_init"); 532 533 return 0; 534} 535 536/* 537 * Disable multicast routing 538 */ 539int 540X_ip_mrouter_done() 541{ 542 vifi_t vifi; 543 int i; 544 struct ifnet *ifp; 545 struct ifreq ifr; 546 struct mbuf *mb_rt; 547 struct mfc *rt; 548 struct mbuf *m; 549 struct rtdetq *rte; 550 int s; 551 552 s = splnet(); 553 554 /* 555 * For each phyint in use, disable promiscuous reception of all IP 556 * multicasts. 557 */ 558 for (vifi = 0; vifi < numvifs; vifi++) { 559 if (viftable[vifi].v_lcl_addr.s_addr != 0 && 560 !(viftable[vifi].v_flags & VIFF_TUNNEL)) { 561 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET; 562 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr 563 = INADDR_ANY; 564 ifp = viftable[vifi].v_ifp; 565 (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr); 566 } 567 } 568 bzero((caddr_t)qtable, sizeof(qtable)); 569 bzero((caddr_t)tbftable, sizeof(tbftable)); 570 bzero((caddr_t)viftable, sizeof(viftable)); 571 numvifs = 0; 572 pim_assert = 0; 573 574 untimeout(expire_upcalls, (caddr_t)NULL); 575 576 /* 577 * Free all multicast forwarding cache entries. 578 */ 579 for (i = 0; i < MFCTBLSIZ; i++) { 580 mb_rt = mfctable[i]; 581 while (mb_rt) { 582 if (mb_rt->m_act != NULL) { 583 while (mb_rt->m_act) { 584 m = mb_rt->m_act; 585 mb_rt->m_act = m->m_act; 586 rte = mtod(m, struct rtdetq *); 587 m_freem(rte->m); 588 m_free(m); 589 } 590 } 591 mb_rt = m_free(mb_rt); 592 } 593 } 594 595 bzero((caddr_t)mfctable, sizeof(mfctable)); 596 597 /* 598 * Reset de-encapsulation cache 599 */ 600 last_encap_src = NULL; 601 last_encap_vif = NULL; 602 have_encap_tunnel = 0; 603 604 ip_mrouter = NULL; 605 606 splx(s); 607 608 if (mrtdebug) 609 log(LOG_DEBUG, "ip_mrouter_done"); 610 611 return 0; 612} 613 614#ifndef MROUTE_LKM 615int (*ip_mrouter_done)(void) = X_ip_mrouter_done; 616#endif 617 618static int 619get_version(mb) 620 struct mbuf *mb; 621{ 622 int *v; 623 624 v = mtod(mb, int *); 625 626 *v = 0x0305; /* XXX !!!! */ 627 mb->m_len = sizeof(int); 628 629 return 0; 630} 631 632/* 633 * Set PIM assert processing global 634 */ 635static int 636set_assert(i) 637 int *i; 638{ 639 if ((*i != 1) && (*i != 0)) 640 return EINVAL; 641 642 pim_assert = *i; 643 644 return 0; 645} 646 647/* 648 * Get PIM assert processing global 649 */ 650static int 651get_assert(m) 652 struct mbuf *m; 653{ 654 int *i; 655 656 i = mtod(m, int *); 657 658 *i = pim_assert; 659 660 return 0; 661} 662 663/* 664 * Add a vif to the vif table 665 */ 666static int 667add_vif(vifcp) 668 register struct vifctl *vifcp; 669{ 670 register struct vif *vifp = viftable + vifcp->vifc_vifi; 671 static struct sockaddr_in sin = {sizeof sin, AF_INET}; 672 struct ifaddr *ifa; 673 struct ifnet *ifp; 674 struct ifreq ifr; 675 int error, s; 676 struct tbf *v_tbf = tbftable + vifcp->vifc_vifi; 677 678 if (vifcp->vifc_vifi >= MAXVIFS) return EINVAL; 679 if (vifp->v_lcl_addr.s_addr != 0) return EADDRINUSE; 680 681 /* Find the interface with an address in AF_INET family */ 682 sin.sin_addr = vifcp->vifc_lcl_addr; 683 ifa = ifa_ifwithaddr((struct sockaddr *)&sin); 684 if (ifa == 0) return EADDRNOTAVAIL; 685 ifp = ifa->ifa_ifp; 686 687 if (vifcp->vifc_flags & VIFF_TUNNEL) { 688 if ((vifcp->vifc_flags & VIFF_SRCRT) == 0) { 689 /* 690 * An encapsulating tunnel is wanted. Tell ipip_input() to 691 * start paying attention to encapsulated packets. 692 */ 693 if (have_encap_tunnel == 0) { 694 have_encap_tunnel = 1; 695 for (s = 0; s < MAXVIFS; ++s) { 696 multicast_decap_if[s].if_name = "mdecap"; 697 multicast_decap_if[s].if_unit = s; 698 } 699 } 700 /* 701 * Set interface to fake encapsulator interface 702 */ 703 ifp = &multicast_decap_if[vifcp->vifc_vifi]; 704 /* 705 * Prepare cached route entry 706 */ 707 bzero(&vifp->v_route, sizeof(vifp->v_route)); 708 } else { 709 log(LOG_ERR, "Source routed tunnels not supported."); 710 return EOPNOTSUPP; 711 } 712 } else { 713 /* Make sure the interface supports multicast */ 714 if ((ifp->if_flags & IFF_MULTICAST) == 0) 715 return EOPNOTSUPP; 716 717 /* Enable promiscuous reception of all IP multicasts from the if */ 718 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET; 719 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr = INADDR_ANY; 720 s = splnet(); 721 error = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, (caddr_t)&ifr); 722 splx(s); 723 if (error) 724 return error; 725 } 726 727 s = splnet(); 728 /* define parameters for the tbf structure */ 729 vifp->v_tbf = v_tbf; 730 vifp->v_tbf->q_len = 0; 731 vifp->v_tbf->n_tok = 0; 732 vifp->v_tbf->last_pkt_t = 0; 733 734 vifp->v_flags = vifcp->vifc_flags; 735 vifp->v_threshold = vifcp->vifc_threshold; 736 vifp->v_lcl_addr = vifcp->vifc_lcl_addr; 737 vifp->v_rmt_addr = vifcp->vifc_rmt_addr; 738 vifp->v_ifp = ifp; 739 vifp->v_rate_limit= vifcp->vifc_rate_limit; 740 vifp->v_rsvp_on = 0; 741 vifp->v_rsvpd = NULL; 742 /* initialize per vif pkt counters */ 743 vifp->v_pkt_in = 0; 744 vifp->v_pkt_out = 0; 745 vifp->v_bytes_in = 0; 746 vifp->v_bytes_out = 0; 747 splx(s); 748 749 /* Adjust numvifs up if the vifi is higher than numvifs */ 750 if (numvifs <= vifcp->vifc_vifi) numvifs = vifcp->vifc_vifi + 1; 751 752 if (mrtdebug) 753 log(LOG_DEBUG, "add_vif #%d, lcladdr %x, %s %x, thresh %x, rate %d", 754 vifcp->vifc_vifi, 755 ntohl(vifcp->vifc_lcl_addr.s_addr), 756 (vifcp->vifc_flags & VIFF_TUNNEL) ? "rmtaddr" : "mask", 757 ntohl(vifcp->vifc_rmt_addr.s_addr), 758 vifcp->vifc_threshold, 759 vifcp->vifc_rate_limit); 760 761 return 0; 762} 763 764/* 765 * Delete a vif from the vif table 766 */ 767static int 768del_vif(vifip) 769 vifi_t *vifip; 770{ 771 register struct vif *vifp = viftable + *vifip; 772 register vifi_t vifi; 773 struct ifnet *ifp; 774 struct ifreq ifr; 775 int s; 776 777 if (*vifip >= numvifs) return EINVAL; 778 if (vifp->v_lcl_addr.s_addr == 0) return EADDRNOTAVAIL; 779 780 s = splnet(); 781 782 if (!(vifp->v_flags & VIFF_TUNNEL)) { 783 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET; 784 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr = INADDR_ANY; 785 ifp = vifp->v_ifp; 786 (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr); 787 } 788 789 if (vifp == last_encap_vif) { 790 last_encap_vif = 0; 791 last_encap_src = 0; 792 } 793 794 bzero((caddr_t)qtable[*vifip], 795 sizeof(qtable[*vifip])); 796 bzero((caddr_t)vifp->v_tbf, sizeof(*(vifp->v_tbf))); 797 bzero((caddr_t)vifp, sizeof (*vifp)); 798 799 /* Adjust numvifs down */ 800 for (vifi = numvifs; vifi > 0; vifi--) 801 if (viftable[vifi-1].v_lcl_addr.s_addr != 0) break; 802 numvifs = vifi; 803 804 splx(s); 805 806 if (mrtdebug) 807 log(LOG_DEBUG, "del_vif %d, numvifs %d", *vifip, numvifs); 808 809 return 0; 810} 811 812/* 813 * Add an mfc entry 814 */ 815static int 816add_mfc(mfccp) 817 struct mfcctl *mfccp; 818{ 819 struct mfc *rt; 820 register struct mbuf *mb_rt; 821 u_long hash; 822 struct mbuf *mb_ntry; 823 struct rtdetq *rte; 824 register u_short nstl; 825 int s; 826 int i; 827 828 MFCFIND(mfccp->mfcc_origin.s_addr, mfccp->mfcc_mcastgrp.s_addr, rt); 829 830 /* If an entry already exists, just update the fields */ 831 if (rt) { 832 if (mrtdebug & DEBUG_MFC) 833 log(LOG_DEBUG,"add_mfc update o %x g %x p %x", 834 ntohl(mfccp->mfcc_origin.s_addr), 835 ntohl(mfccp->mfcc_mcastgrp.s_addr), 836 mfccp->mfcc_parent); 837 838 s = splnet(); 839 rt->mfc_parent = mfccp->mfcc_parent; 840 for (i = 0; i < numvifs; i++) 841 rt->mfc_ttls[i] = mfccp->mfcc_ttls[i]; 842 splx(s); 843 return 0; 844 } 845 846 /* 847 * Find the entry for which the upcall was made and update 848 */ 849 s = splnet(); 850 hash = MFCHASH(mfccp->mfcc_origin.s_addr, mfccp->mfcc_mcastgrp.s_addr); 851 for (mb_rt = mfctable[hash], nstl = 0; mb_rt; mb_rt = mb_rt->m_next) { 852 853 rt = mtod(mb_rt, struct mfc *); 854 if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) && 855 (rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr) && 856 (mb_rt->m_act != NULL)) { 857 858 if (nstl++) 859 log(LOG_ERR, "add_mfc %s o %x g %x p %x dbx %x", 860 "multiple kernel entries", 861 ntohl(mfccp->mfcc_origin.s_addr), 862 ntohl(mfccp->mfcc_mcastgrp.s_addr), 863 mfccp->mfcc_parent, mb_rt->m_act); 864 865 if (mrtdebug & DEBUG_MFC) 866 log(LOG_DEBUG,"add_mfc o %x g %x p %x dbg %x", 867 ntohl(mfccp->mfcc_origin.s_addr), 868 ntohl(mfccp->mfcc_mcastgrp.s_addr), 869 mfccp->mfcc_parent, mb_rt->m_act); 870 871 rt->mfc_origin = mfccp->mfcc_origin; 872 rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp; 873 rt->mfc_parent = mfccp->mfcc_parent; 874 for (i = 0; i < numvifs; i++) 875 rt->mfc_ttls[i] = mfccp->mfcc_ttls[i]; 876 /* initialize pkt counters per src-grp */ 877 rt->mfc_pkt_cnt = 0; 878 rt->mfc_byte_cnt = 0; 879 rt->mfc_wrong_if = 0; 880 rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0; 881 882 rt->mfc_expire = 0; /* Don't clean this guy up */ 883 nexpire[hash]--; 884 885 /* free packets Qed at the end of this entry */ 886 while (mb_rt->m_act) { 887 mb_ntry = mb_rt->m_act; 888 rte = mtod(mb_ntry, struct rtdetq *); 889/* #ifdef RSVP_ISI */ 890 ip_mdq(rte->m, rte->ifp, rt, -1); 891/* #endif */ 892 mb_rt->m_act = mb_ntry->m_act; 893 m_freem(rte->m); 894#ifdef UPCALL_TIMING 895 collate(&(rte->t)); 896#endif /* UPCALL_TIMING */ 897 m_free(mb_ntry); 898 } 899 } 900 } 901 902 /* 903 * It is possible that an entry is being inserted without an upcall 904 */ 905 if (nstl == 0) { 906 if (mrtdebug & DEBUG_MFC) 907 log(LOG_DEBUG,"add_mfc no upcall h %d o %x g %x p %x", 908 hash, ntohl(mfccp->mfcc_origin.s_addr), 909 ntohl(mfccp->mfcc_mcastgrp.s_addr), 910 mfccp->mfcc_parent); 911 912 for (mb_rt = mfctable[hash]; mb_rt; mb_rt = mb_rt->m_next) { 913 914 rt = mtod(mb_rt, struct mfc *); 915 if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) && 916 (rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr)) { 917 918 rt->mfc_origin = mfccp->mfcc_origin; 919 rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp; 920 rt->mfc_parent = mfccp->mfcc_parent; 921 for (i = 0; i < numvifs; i++) 922 rt->mfc_ttls[i] = mfccp->mfcc_ttls[i]; 923 /* initialize pkt counters per src-grp */ 924 rt->mfc_pkt_cnt = 0; 925 rt->mfc_byte_cnt = 0; 926 rt->mfc_wrong_if = 0; 927 rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0; 928 if (rt->mfc_expire) 929 nexpire[hash]--; 930 rt->mfc_expire = 0; 931 } 932 } 933 if (mb_rt == NULL) { 934 /* no upcall, so make a new entry */ 935 MGET(mb_rt, M_DONTWAIT, MT_MRTABLE); 936 if (mb_rt == NULL) { 937 splx(s); 938 return ENOBUFS; 939 } 940 941 rt = mtod(mb_rt, struct mfc *); 942 943 /* insert new entry at head of hash chain */ 944 rt->mfc_origin = mfccp->mfcc_origin; 945 rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp; 946 rt->mfc_parent = mfccp->mfcc_parent; 947 for (i = 0; i < numvifs; i++) 948 rt->mfc_ttls[i] = mfccp->mfcc_ttls[i]; 949 /* initialize pkt counters per src-grp */ 950 rt->mfc_pkt_cnt = 0; 951 rt->mfc_byte_cnt = 0; 952 rt->mfc_wrong_if = 0; 953 rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0; 954 rt->mfc_expire = 0; 955 956 /* link into table */ 957 mb_rt->m_next = mfctable[hash]; 958 mfctable[hash] = mb_rt; 959 mb_rt->m_act = NULL; 960 } 961 } 962 splx(s); 963 return 0; 964} 965 966#ifdef UPCALL_TIMING 967/* 968 * collect delay statistics on the upcalls 969 */ 970static void collate(t) 971register struct timeval *t; 972{ 973 register u_long d; 974 register struct timeval tp; 975 register u_long delta; 976 977 GET_TIME(tp); 978 979 if (TV_LT(*t, tp)) 980 { 981 TV_DELTA(tp, *t, delta); 982 983 d = delta >> 10; 984 if (d > 50) 985 d = 50; 986 987 ++upcall_data[d]; 988 } 989} 990#endif /* UPCALL_TIMING */ 991 992/* 993 * Delete an mfc entry 994 */ 995static int 996del_mfc(mfccp) 997 struct mfcctl *mfccp; 998{ 999 struct in_addr origin; 1000 struct in_addr mcastgrp; 1001 struct mfc *rt; 1002 struct mbuf *mb_rt; 1003 struct mbuf **nptr; 1004 u_long hash; 1005 int s, i; 1006 1007 origin = mfccp->mfcc_origin; 1008 mcastgrp = mfccp->mfcc_mcastgrp; 1009 hash = MFCHASH(origin.s_addr, mcastgrp.s_addr); 1010 1011 if (mrtdebug & DEBUG_MFC) 1012 log(LOG_DEBUG,"del_mfc orig %x mcastgrp %x", 1013 ntohl(origin.s_addr), ntohl(mcastgrp.s_addr)); 1014 1015 s = splnet(); 1016 1017 nptr = &mfctable[hash]; 1018 while ((mb_rt = *nptr) != NULL) { 1019 rt = mtod(mb_rt, struct mfc *); 1020 if (origin.s_addr == rt->mfc_origin.s_addr && 1021 mcastgrp.s_addr == rt->mfc_mcastgrp.s_addr && 1022 mb_rt->m_act == NULL) 1023 break; 1024 1025 nptr = &mb_rt->m_next; 1026 } 1027 if (mb_rt == NULL) { 1028 splx(s); 1029 return EADDRNOTAVAIL; 1030 } 1031 1032 MFREE(mb_rt, *nptr); 1033 1034 splx(s); 1035 1036 return 0; 1037} 1038 1039/* 1040 * Send a message to mrouted on the multicast routing socket 1041 */ 1042static int 1043socket_send(s, mm, src) 1044 struct socket *s; 1045 struct mbuf *mm; 1046 struct sockaddr_in *src; 1047{ 1048 if (s) { 1049 if (sbappendaddr(&s->so_rcv, 1050 (struct sockaddr *)src, 1051 mm, (struct mbuf *)0) != 0) { 1052 sorwakeup(s); 1053 return 0; 1054 } 1055 } 1056 m_freem(mm); 1057 return -1; 1058} 1059 1060/* 1061 * IP multicast forwarding function. This function assumes that the packet 1062 * pointed to by "ip" has arrived on (or is about to be sent to) the interface 1063 * pointed to by "ifp", and the packet is to be relayed to other networks 1064 * that have members of the packet's destination IP multicast group. 1065 * 1066 * The packet is returned unscathed to the caller, unless it is 1067 * erroneous, in which case a non-zero return value tells the caller to 1068 * discard it. 1069 */ 1070 1071#define IP_HDR_LEN 20 /* # bytes of fixed IP header (excluding options) */ 1072#define TUNNEL_LEN 12 /* # bytes of IP option for tunnel encapsulation */ 1073 1074int 1075X_ip_mforward(ip, ifp, m, imo) 1076 register struct ip *ip; 1077 struct ifnet *ifp; 1078 struct mbuf *m; 1079 struct ip_moptions *imo; 1080{ 1081 register struct mfc *rt = 0; /* XXX uninit warning */ 1082 register u_char *ipoptions; 1083 static struct sockproto k_igmpproto = { AF_INET, IPPROTO_IGMP }; 1084 static struct sockaddr_in k_igmpsrc = { sizeof k_igmpsrc, AF_INET }; 1085 static int srctun = 0; 1086 register struct mbuf *mm; 1087 int s; 1088 vifi_t vifi; 1089 struct vif *vifp; 1090 1091 if (mrtdebug & DEBUG_FORWARD) 1092 log(LOG_DEBUG, "ip_mforward: src %x, dst %x, ifp %x", 1093 ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr), ifp); 1094 1095 if (ip->ip_hl < (IP_HDR_LEN + TUNNEL_LEN) >> 2 || 1096 (ipoptions = (u_char *)(ip + 1))[1] != IPOPT_LSRR ) { 1097 /* 1098 * Packet arrived via a physical interface or 1099 * an encapsulated tunnel. 1100 */ 1101 } else { 1102 /* 1103 * Packet arrived through a source-route tunnel. 1104 * Source-route tunnels are no longer supported. 1105 */ 1106 if ((srctun++ % 1000) == 0) 1107 log(LOG_ERR, "ip_mforward: received source-routed packet from %x", 1108 ntohl(ip->ip_src.s_addr)); 1109 1110 return 1; 1111 } 1112 1113 if ((imo) && ((vifi = imo->imo_multicast_vif) < numvifs)) { 1114 if (ip->ip_ttl < 255) 1115 ip->ip_ttl++; /* compensate for -1 in *_send routines */ 1116 if (rsvpdebug && ip->ip_p == IPPROTO_RSVP) { 1117 vifp = viftable + vifi; 1118 printf("Sending IPPROTO_RSVP from %x to %x on vif %d (%s%s%d)\n", 1119 ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr), vifi, 1120 (vifp->v_flags & VIFF_TUNNEL) ? "tunnel on " : "", 1121 vifp->v_ifp->if_name, vifp->v_ifp->if_unit); 1122 } 1123 return (ip_mdq(m, ifp, rt, vifi)); 1124 } 1125 if (rsvpdebug && ip->ip_p == IPPROTO_RSVP) { 1126 printf("Warning: IPPROTO_RSVP from %x to %x without vif option\n", 1127 ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr)); 1128 } 1129 1130 /* 1131 * Don't forward a packet with time-to-live of zero or one, 1132 * or a packet destined to a local-only group. 1133 */ 1134 if (ip->ip_ttl <= 1 || 1135 ntohl(ip->ip_dst.s_addr) <= INADDR_MAX_LOCAL_GROUP) 1136 return 0; 1137 1138 /* 1139 * Determine forwarding vifs from the forwarding cache table 1140 */ 1141 s = splnet(); 1142 MFCFIND(ip->ip_src.s_addr, ip->ip_dst.s_addr, rt); 1143 1144 /* Entry exists, so forward if necessary */ 1145 if (rt != NULL) { 1146 splx(s); 1147 return (ip_mdq(m, ifp, rt, -1)); 1148 } else { 1149 /* 1150 * If we don't have a route for packet's origin, 1151 * Make a copy of the packet & 1152 * send message to routing daemon 1153 */ 1154 1155 register struct mbuf *mb_rt; 1156 register struct mbuf *mb_ntry; 1157 register struct mbuf *mb0; 1158 register struct rtdetq *rte; 1159 register struct mbuf *rte_m; 1160 register u_long hash; 1161 register int npkts; 1162#ifdef UPCALL_TIMING 1163 struct timeval tp; 1164 1165 GET_TIME(tp); 1166#endif 1167 1168 mrtstat.mrts_no_route++; 1169 if (mrtdebug & (DEBUG_FORWARD | DEBUG_MFC)) 1170 log(LOG_DEBUG, "ip_mforward: no rte s %x g %x", 1171 ntohl(ip->ip_src.s_addr), 1172 ntohl(ip->ip_dst.s_addr)); 1173 1174 /* 1175 * Allocate mbufs early so that we don't do extra work if we are 1176 * just going to fail anyway. 1177 */ 1178 MGET(mb_ntry, M_DONTWAIT, MT_DATA); 1179 if (mb_ntry == NULL) { 1180 splx(s); 1181 return ENOBUFS; 1182 } 1183 mb0 = m_copy(m, 0, M_COPYALL); 1184 if (mb0 == NULL) { 1185 m_free(mb_ntry); 1186 splx(s); 1187 return ENOBUFS; 1188 } 1189 1190 /* is there an upcall waiting for this packet? */ 1191 hash = MFCHASH(ip->ip_src.s_addr, ip->ip_dst.s_addr); 1192 for (mb_rt = mfctable[hash]; mb_rt; mb_rt = mb_rt->m_next) { 1193 rt = mtod(mb_rt, struct mfc *); 1194 if ((ip->ip_src.s_addr == rt->mfc_origin.s_addr) && 1195 (ip->ip_dst.s_addr == rt->mfc_mcastgrp.s_addr) && 1196 (mb_rt->m_act != NULL)) 1197 break; 1198 } 1199 1200 if (mb_rt == NULL) { 1201 int hlen = ip->ip_hl << 2; 1202 int i; 1203 struct igmpmsg *im; 1204 1205 /* no upcall, so make a new entry */ 1206 MGET(mb_rt, M_DONTWAIT, MT_MRTABLE); 1207 if (mb_rt == NULL) { 1208 m_free(mb_ntry); 1209 m_freem(mb0); 1210 splx(s); 1211 return ENOBUFS; 1212 } 1213 /* Make a copy of the header to send to the user level process */ 1214 mm = m_copy(m, 0, hlen); 1215 if (mm && (M_HASCL(mm) || mm->m_len < hlen)) 1216 mm = m_pullup(mm, hlen); 1217 if (mm == NULL) { 1218 m_free(mb_ntry); 1219 m_freem(mb0); 1220 m_free(mb_rt); 1221 splx(s); 1222 return ENOBUFS; 1223 } 1224 1225 /* 1226 * Send message to routing daemon to install 1227 * a route into the kernel table 1228 */ 1229 k_igmpsrc.sin_addr = ip->ip_src; 1230 1231 im = mtod(mm, struct igmpmsg *); 1232 im->im_msgtype = IGMPMSG_NOCACHE; 1233 im->im_mbz = 0; 1234 1235 mrtstat.mrts_upcalls++; 1236 1237 if (socket_send(ip_mrouter, mm, &k_igmpsrc) < 0) { 1238 log(LOG_WARNING, "ip_mforward: ip_mrouter socket queue full"); 1239 ++mrtstat.mrts_upq_sockfull; 1240 m_free(mb_ntry); 1241 m_freem(mb0); 1242 m_free(mb_rt); 1243 splx(s); 1244 return ENOBUFS; 1245 } 1246 1247 rt = mtod(mb_rt, struct mfc *); 1248 1249 /* insert new entry at head of hash chain */ 1250 rt->mfc_origin.s_addr = ip->ip_src.s_addr; 1251 rt->mfc_mcastgrp.s_addr = ip->ip_dst.s_addr; 1252 rt->mfc_expire = UPCALL_EXPIRE; 1253 nexpire[hash]++; 1254 for (i = 0; i < numvifs; i++) 1255 rt->mfc_ttls[i] = 0; 1256 rt->mfc_parent = -1; 1257 1258 /* link into table */ 1259 mb_rt->m_next = mfctable[hash]; 1260 mfctable[hash] = mb_rt; 1261 mb_rt->m_act = NULL; 1262 1263 rte_m = mb_rt; 1264 } else { 1265 /* determine if q has overflowed */ 1266 for (rte_m = mb_rt, npkts = 0; rte_m->m_act; rte_m = rte_m->m_act) 1267 npkts++; 1268 1269 if (npkts > MAX_UPQ) { 1270 mrtstat.mrts_upq_ovflw++; 1271 m_free(mb_ntry); 1272 m_freem(mb0); 1273 splx(s); 1274 return 0; 1275 } 1276 } 1277 1278 mb_ntry->m_act = NULL; 1279 rte = mtod(mb_ntry, struct rtdetq *); 1280 1281 rte->m = mb0; 1282 rte->ifp = ifp; 1283#ifdef UPCALL_TIMING 1284 rte->t = tp; 1285#endif 1286 1287 /* Add this entry to the end of the queue */ 1288 rte_m->m_act = mb_ntry; 1289 1290 splx(s); 1291 1292 return 0; 1293 } 1294} 1295 1296#ifndef MROUTE_LKM 1297int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *, 1298 struct ip_moptions *) = X_ip_mforward; 1299#endif 1300 1301/* 1302 * Clean up the cache entry if upcall is not serviced 1303 */ 1304static void 1305expire_upcalls(void *unused) 1306{ 1307 struct mbuf *mb_rt, *m, **nptr; 1308 struct rtdetq *rte; 1309 struct mfc *mfc; 1310 int i; 1311 int s; 1312 1313 s = splnet(); 1314 for (i = 0; i < MFCTBLSIZ; i++) { 1315 if (nexpire[i] == 0) 1316 continue; 1317 nptr = &mfctable[i]; 1318 for (mb_rt = *nptr; mb_rt != NULL; mb_rt = *nptr) { 1319 mfc = mtod(mb_rt, struct mfc *); 1320 1321 /* 1322 * Skip real cache entries 1323 * Make sure it wasn't marked to not expire (shouldn't happen) 1324 * If it expires now 1325 */ 1326 if (mb_rt->m_act != NULL && 1327 mfc->mfc_expire != 0 && 1328 --mfc->mfc_expire == 0) { 1329 if (mrtdebug & DEBUG_EXPIRE) 1330 log(LOG_DEBUG, "expire_upcalls: expiring (%x %x)", 1331 ntohl(mfc->mfc_origin.s_addr), 1332 ntohl(mfc->mfc_mcastgrp.s_addr)); 1333 /* 1334 * drop all the packets 1335 * free the mbuf with the pkt, if, timing info 1336 */ 1337 while (mb_rt->m_act) { 1338 m = mb_rt->m_act; 1339 mb_rt->m_act = m->m_act; 1340 1341 rte = mtod(m, struct rtdetq *); 1342 m_freem(rte->m); 1343 m_free(m); 1344 } 1345 ++mrtstat.mrts_cache_cleanups; 1346 nexpire[i]--; 1347 1348 MFREE(mb_rt, *nptr); 1349 } else { 1350 nptr = &mb_rt->m_next; 1351 } 1352 } 1353 } 1354 splx(s); 1355 timeout(expire_upcalls, (caddr_t)NULL, EXPIRE_TIMEOUT); 1356} 1357 1358/* 1359 * Packet forwarding routine once entry in the cache is made 1360 */ 1361static int 1362ip_mdq(m, ifp, rt, xmt_vif) 1363 register struct mbuf *m; 1364 register struct ifnet *ifp; 1365 register struct mfc *rt; 1366 register vifi_t xmt_vif; 1367{ 1368 register struct ip *ip = mtod(m, struct ip *); 1369 register vifi_t vifi; 1370 register struct vif *vifp; 1371 register struct mbuf *tmp; 1372 register int plen = ntohs(ip->ip_len); 1373 1374/* 1375 * Macro to send packet on vif. Since RSVP packets don't get counted on 1376 * input, they shouldn't get counted on output, so statistics keeping is 1377 * seperate. 1378 */ 1379#define MC_SEND(ip,vifp,m) { \ 1380 if ((vifp)->v_flags & VIFF_TUNNEL) \ 1381 encap_send((ip), (vifp), (m)); \ 1382 else \ 1383 phyint_send((ip), (vifp), (m)); \ 1384} 1385 1386 /* 1387 * If xmt_vif is not -1, send on only the requested vif. 1388 * 1389 * (since vifi_t is u_short, -1 becomes MAXUSHORT, which > numvifs.) 1390 */ 1391 if (xmt_vif < numvifs) { 1392 MC_SEND(ip, viftable + xmt_vif, m); 1393 return 1; 1394 } 1395 1396 /* 1397 * Don't forward if it didn't arrive from the parent vif for its origin. 1398 */ 1399 vifi = rt->mfc_parent; 1400 if ((vifi >= numvifs) || (viftable[vifi].v_ifp != ifp)) { 1401 /* came in the wrong interface */ 1402 if (mrtdebug & DEBUG_FORWARD) 1403 log(LOG_DEBUG, "wrong if: ifp %x vifi %d vififp %x", 1404 ifp, vifi, viftable[vifi].v_ifp); 1405 ++mrtstat.mrts_wrong_if; 1406 ++rt->mfc_wrong_if; 1407 /* 1408 * If we are doing PIM assert processing, and we are forwarding 1409 * packets on this interface, and it is a broadcast medium 1410 * interface (and not a tunnel), send a message to the routing daemon. 1411 */ 1412 if (pim_assert && rt->mfc_ttls[vifi] && 1413 (ifp->if_flags & IFF_BROADCAST) && 1414 !(viftable[vifi].v_flags & VIFF_TUNNEL)) { 1415 struct sockaddr_in k_igmpsrc; 1416 struct mbuf *mm; 1417 struct igmpmsg *im; 1418 int hlen = ip->ip_hl << 2; 1419 struct timeval now; 1420 register u_long delta; 1421 1422 GET_TIME(now); 1423 1424 TV_DELTA(rt->mfc_last_assert, now, delta); 1425 1426 if (delta > ASSERT_MSG_TIME) { 1427 mm = m_copy(m, 0, hlen); 1428 if (mm && (M_HASCL(mm) || mm->m_len < hlen)) 1429 mm = m_pullup(mm, hlen); 1430 if (mm == NULL) { 1431 return ENOBUFS; 1432 } 1433 1434 rt->mfc_last_assert = now; 1435 1436 im = mtod(mm, struct igmpmsg *); 1437 im->im_msgtype = IGMPMSG_WRONGVIF; 1438 im->im_mbz = 0; 1439 im->im_vif = vifi; 1440 1441 k_igmpsrc.sin_addr = im->im_src; 1442 1443 socket_send(ip_mrouter, m, &k_igmpsrc); 1444 } 1445 } 1446 return 0; 1447 } 1448 1449 /* If I sourced this packet, it counts as output, else it was input. */ 1450 if (ip->ip_src.s_addr == viftable[vifi].v_lcl_addr.s_addr) { 1451 viftable[vifi].v_pkt_out++; 1452 viftable[vifi].v_bytes_out += plen; 1453 } else { 1454 viftable[vifi].v_pkt_in++; 1455 viftable[vifi].v_bytes_in += plen; 1456 } 1457 rt->mfc_pkt_cnt++; 1458 rt->mfc_byte_cnt += plen; 1459 1460 /* 1461 * For each vif, decide if a copy of the packet should be forwarded. 1462 * Forward if: 1463 * - the ttl exceeds the vif's threshold 1464 * - there are group members downstream on interface 1465 */ 1466 for (vifp = viftable, vifi = 0; vifi < numvifs; vifp++, vifi++) 1467 if ((rt->mfc_ttls[vifi] > 0) && 1468 (ip->ip_ttl > rt->mfc_ttls[vifi])) { 1469 vifp->v_pkt_out++; 1470 vifp->v_bytes_out += plen; 1471 MC_SEND(ip, vifp, m); 1472 } 1473 1474 return 0; 1475} 1476 1477/* 1478 * check if a vif number is legal/ok. This is used by ip_output, to export 1479 * numvifs there, 1480 */ 1481int 1482X_legal_vif_num(vif) 1483 int vif; 1484{ 1485 if (vif >= 0 && vif < numvifs) 1486 return(1); 1487 else 1488 return(0); 1489} 1490 1491#ifndef MROUTE_LKM 1492int (*legal_vif_num)(int) = X_legal_vif_num; 1493#endif 1494 1495/* 1496 * Return the local address used by this vif 1497 */ 1498u_long 1499X_ip_mcast_src(vifi) 1500 int vifi; 1501{ 1502 if (vifi >= 0 && vifi < numvifs) 1503 return viftable[vifi].v_lcl_addr.s_addr; 1504 else 1505 return INADDR_ANY; 1506} 1507 1508#ifndef MROUTE_LKM 1509u_long (*ip_mcast_src)(int) = X_ip_mcast_src; 1510#endif 1511 1512static void 1513phyint_send(ip, vifp, m) 1514 struct ip *ip; 1515 struct vif *vifp; 1516 struct mbuf *m; 1517{ 1518 register struct mbuf *mb_copy; 1519 register int hlen = ip->ip_hl << 2; 1520 register struct ip_moptions *imo; 1521 1522 /* 1523 * Make a new reference to the packet; make sure that 1524 * the IP header is actually copied, not just referenced, 1525 * so that ip_output() only scribbles on the copy. 1526 */ 1527 mb_copy = m_copy(m, 0, M_COPYALL); 1528 if (mb_copy && (M_HASCL(mb_copy) || mb_copy->m_len < hlen)) 1529 mb_copy = m_pullup(mb_copy, hlen); 1530 if (mb_copy == NULL) 1531 return; 1532 1533 MALLOC(imo, struct ip_moptions *, sizeof *imo, M_IPMOPTS, M_NOWAIT); 1534 if (imo == NULL) { 1535 m_freem(mb_copy); 1536 return; 1537 } 1538 1539 imo->imo_multicast_ifp = vifp->v_ifp; 1540 imo->imo_multicast_ttl = ip->ip_ttl - 1; 1541 imo->imo_multicast_loop = 1; 1542 imo->imo_multicast_vif = -1; 1543 1544 if (vifp->v_rate_limit <= 0) 1545 tbf_send_packet(vifp, mb_copy, imo); 1546 else 1547 tbf_control(vifp, mb_copy, mtod(mb_copy, struct ip *), ip->ip_len, 1548 imo); 1549} 1550 1551static void 1552encap_send(ip, vifp, m) 1553 register struct ip *ip; 1554 register struct vif *vifp; 1555 register struct mbuf *m; 1556{ 1557 register struct mbuf *mb_copy; 1558 register struct ip *ip_copy; 1559 int hlen = ip->ip_hl << 2; 1560 register int i, len = ip->ip_len; 1561 1562 /* 1563 * copy the old packet & pullup it's IP header into the 1564 * new mbuf so we can modify it. Try to fill the new 1565 * mbuf since if we don't the ethernet driver will. 1566 */ 1567 MGET(mb_copy, M_DONTWAIT, MT_DATA); 1568 if (mb_copy == NULL) 1569 return; 1570 mb_copy->m_data += 16; 1571 mb_copy->m_len = sizeof(multicast_encap_iphdr); 1572 1573 if ((mb_copy->m_next = m_copy(m, 0, M_COPYALL)) == NULL) { 1574 m_freem(mb_copy); 1575 return; 1576 } 1577 i = MHLEN - M_LEADINGSPACE(mb_copy); 1578 if (i > len) 1579 i = len; 1580 mb_copy = m_pullup(mb_copy, i); 1581 if (mb_copy == NULL) 1582 return; 1583 mb_copy->m_pkthdr.len = len + sizeof(multicast_encap_iphdr); 1584 1585 /* 1586 * fill in the encapsulating IP header. 1587 */ 1588 ip_copy = mtod(mb_copy, struct ip *); 1589 *ip_copy = multicast_encap_iphdr; 1590 ip_copy->ip_id = htons(ip_id++); 1591 ip_copy->ip_len += len; 1592 ip_copy->ip_src = vifp->v_lcl_addr; 1593 ip_copy->ip_dst = vifp->v_rmt_addr; 1594 1595 /* 1596 * turn the encapsulated IP header back into a valid one. 1597 */ 1598 ip = (struct ip *)((caddr_t)ip_copy + sizeof(multicast_encap_iphdr)); 1599 --ip->ip_ttl; 1600 HTONS(ip->ip_len); 1601 HTONS(ip->ip_off); 1602 ip->ip_sum = 0; 1603#if defined(LBL) && !defined(ultrix) 1604 ip->ip_sum = ~oc_cksum((caddr_t)ip, ip->ip_hl << 2, 0); 1605#else 1606 mb_copy->m_data += sizeof(multicast_encap_iphdr); 1607 ip->ip_sum = in_cksum(mb_copy, ip->ip_hl << 2); 1608 mb_copy->m_data -= sizeof(multicast_encap_iphdr); 1609#endif 1610 1611 if (vifp->v_rate_limit <= 0) 1612 tbf_send_packet(vifp, mb_copy, 0); 1613 else 1614 tbf_control(vifp, mb_copy, ip, ip_copy->ip_len, 0); 1615} 1616 1617/* 1618 * De-encapsulate a packet and feed it back through ip input (this 1619 * routine is called whenever IP gets a packet with proto type 1620 * ENCAP_PROTO and a local destination address). 1621 */ 1622void 1623#ifdef MROUTE_LKM 1624X_ipip_input(m) 1625#else 1626ipip_input(m, iphlen) 1627#endif 1628 register struct mbuf *m; 1629 int iphlen; 1630{ 1631 struct ifnet *ifp = m->m_pkthdr.rcvif; 1632 register struct ip *ip = mtod(m, struct ip *); 1633 register int hlen = ip->ip_hl << 2; 1634 register int s; 1635 register struct ifqueue *ifq; 1636 register struct vif *vifp; 1637 1638 if (!have_encap_tunnel) { 1639 rip_input(m); 1640 return; 1641 } 1642 /* 1643 * dump the packet if it's not to a multicast destination or if 1644 * we don't have an encapsulating tunnel with the source. 1645 * Note: This code assumes that the remote site IP address 1646 * uniquely identifies the tunnel (i.e., that this site has 1647 * at most one tunnel with the remote site). 1648 */ 1649 if (! IN_MULTICAST(ntohl(((struct ip *)((char *)ip + hlen))->ip_dst.s_addr))) { 1650 ++mrtstat.mrts_bad_tunnel; 1651 m_freem(m); 1652 return; 1653 } 1654 if (ip->ip_src.s_addr != last_encap_src) { 1655 register struct vif *vife; 1656 1657 vifp = viftable; 1658 vife = vifp + numvifs; 1659 last_encap_src = ip->ip_src.s_addr; 1660 last_encap_vif = 0; 1661 for ( ; vifp < vife; ++vifp) 1662 if (vifp->v_rmt_addr.s_addr == ip->ip_src.s_addr) { 1663 if ((vifp->v_flags & (VIFF_TUNNEL|VIFF_SRCRT)) 1664 == VIFF_TUNNEL) 1665 last_encap_vif = vifp; 1666 break; 1667 } 1668 } 1669 if ((vifp = last_encap_vif) == 0) { 1670 last_encap_src = 0; 1671 mrtstat.mrts_cant_tunnel++; /*XXX*/ 1672 m_freem(m); 1673 if (mrtdebug) 1674 log(LOG_DEBUG, "ip_mforward: no tunnel with %x", 1675 ntohl(ip->ip_src.s_addr)); 1676 return; 1677 } 1678 ifp = vifp->v_ifp; 1679 1680 if (hlen > IP_HDR_LEN) 1681 ip_stripoptions(m, (struct mbuf *) 0); 1682 m->m_data += IP_HDR_LEN; 1683 m->m_len -= IP_HDR_LEN; 1684 m->m_pkthdr.len -= IP_HDR_LEN; 1685 m->m_pkthdr.rcvif = ifp; 1686 1687 ifq = &ipintrq; 1688 s = splimp(); 1689 if (IF_QFULL(ifq)) { 1690 IF_DROP(ifq); 1691 m_freem(m); 1692 } else { 1693 IF_ENQUEUE(ifq, m); 1694 /* 1695 * normally we would need a "schednetisr(NETISR_IP)" 1696 * here but we were called by ip_input and it is going 1697 * to loop back & try to dequeue the packet we just 1698 * queued as soon as we return so we avoid the 1699 * unnecessary software interrrupt. 1700 */ 1701 } 1702 splx(s); 1703} 1704 1705/* 1706 * Token bucket filter module 1707 */ 1708static void 1709tbf_control(vifp, m, ip, p_len, imo) 1710 register struct vif *vifp; 1711 register struct mbuf *m; 1712 register struct ip *ip; 1713 register u_long p_len; 1714 struct ip_moptions *imo; 1715{ 1716 tbf_update_tokens(vifp); 1717 1718 /* if there are enough tokens, 1719 * and the queue is empty, 1720 * send this packet out 1721 */ 1722 1723 if (vifp->v_tbf->q_len == 0) { 1724 if (p_len <= vifp->v_tbf->n_tok) { 1725 vifp->v_tbf->n_tok -= p_len; 1726 tbf_send_packet(vifp, m, imo); 1727 } else if (p_len > MAX_BKT_SIZE) { 1728 /* drop if packet is too large */ 1729 mrtstat.mrts_pkt2large++; 1730 m_freem(m); 1731 return; 1732 } else { 1733 /* queue packet and timeout till later */ 1734 tbf_queue(vifp, m, ip, imo); 1735 timeout(tbf_reprocess_q, (caddr_t)vifp, 1); 1736 } 1737 } else if (vifp->v_tbf->q_len < MAXQSIZE) { 1738 /* finite queue length, so queue pkts and process queue */ 1739 tbf_queue(vifp, m, ip, imo); 1740 tbf_process_q(vifp); 1741 } else { 1742 /* queue length too much, try to dq and queue and process */ 1743 if (!tbf_dq_sel(vifp, ip)) { 1744 mrtstat.mrts_q_overflow++; 1745 m_freem(m); 1746 return; 1747 } else { 1748 tbf_queue(vifp, m, ip, imo); 1749 tbf_process_q(vifp); 1750 } 1751 } 1752 return; 1753} 1754 1755/* 1756 * adds a packet to the queue at the interface 1757 */ 1758static void 1759tbf_queue(vifp, m, ip, imo) 1760 register struct vif *vifp; 1761 register struct mbuf *m; 1762 register struct ip *ip; 1763 struct ip_moptions *imo; 1764{ 1765 register u_long ql; 1766 register int index = (vifp - viftable); 1767 register int s = splnet(); 1768 1769 ql = vifp->v_tbf->q_len; 1770 1771 qtable[index][ql].pkt_m = m; 1772 qtable[index][ql].pkt_len = (mtod(m, struct ip *))->ip_len; 1773 qtable[index][ql].pkt_ip = ip; 1774 qtable[index][ql].pkt_imo = imo; 1775 1776 vifp->v_tbf->q_len++; 1777 splx(s); 1778} 1779 1780 1781/* 1782 * processes the queue at the interface 1783 */ 1784static void 1785tbf_process_q(vifp) 1786 register struct vif *vifp; 1787{ 1788 register struct pkt_queue pkt_1; 1789 register int index = (vifp - viftable); 1790 register int s = splnet(); 1791 1792 /* loop through the queue at the interface and send as many packets 1793 * as possible 1794 */ 1795 while (vifp->v_tbf->q_len > 0) { 1796 /* locate the first packet */ 1797 pkt_1.pkt_len = (qtable[index][0]).pkt_len; 1798 pkt_1.pkt_m = (qtable[index][0]).pkt_m; 1799 pkt_1.pkt_ip = (qtable[index][0]).pkt_ip; 1800 pkt_1.pkt_imo = (qtable[index][0]).pkt_imo; 1801 1802 /* determine if the packet can be sent */ 1803 if (pkt_1.pkt_len <= vifp->v_tbf->n_tok) { 1804 /* if so, 1805 * reduce no of tokens, dequeue the queue, 1806 * send the packet. 1807 */ 1808 vifp->v_tbf->n_tok -= pkt_1.pkt_len; 1809 1810 tbf_dequeue(vifp, 0); 1811 1812 tbf_send_packet(vifp, pkt_1.pkt_m, pkt_1.pkt_imo); 1813 1814 } else break; 1815 } 1816 splx(s); 1817} 1818 1819/* 1820 * removes the jth packet from the queue at the interface 1821 */ 1822static void 1823tbf_dequeue(vifp,j) 1824 register struct vif *vifp; 1825 register int j; 1826{ 1827 register u_long index = vifp - viftable; 1828 register int i; 1829 1830 for (i=j+1; i <= vifp->v_tbf->q_len - 1; i++) { 1831 qtable[index][i-1].pkt_m = qtable[index][i].pkt_m; 1832 qtable[index][i-1].pkt_len = qtable[index][i].pkt_len; 1833 qtable[index][i-1].pkt_ip = qtable[index][i].pkt_ip; 1834 qtable[index][i-1].pkt_imo = qtable[index][i].pkt_imo; 1835 } 1836 qtable[index][i-1].pkt_m = NULL; 1837 qtable[index][i-1].pkt_len = NULL; 1838 qtable[index][i-1].pkt_ip = NULL; 1839 qtable[index][i-1].pkt_imo = NULL; 1840 1841 vifp->v_tbf->q_len--; 1842 1843 if (tbfdebug > 1) 1844 log(LOG_DEBUG, "tbf_dequeue: vif# %d qlen %d",vifp-viftable, i-1); 1845} 1846 1847static void 1848tbf_reprocess_q(xvifp) 1849 void *xvifp; 1850{ 1851 register struct vif *vifp = xvifp; 1852 if (ip_mrouter == NULL) 1853 return; 1854 1855 tbf_update_tokens(vifp); 1856 1857 tbf_process_q(vifp); 1858 1859 if (vifp->v_tbf->q_len) 1860 timeout(tbf_reprocess_q, (caddr_t)vifp, 1); 1861} 1862 1863/* function that will selectively discard a member of the queue 1864 * based on the precedence value and the priority obtained through 1865 * a lookup table - not yet implemented accurately! 1866 */ 1867static int 1868tbf_dq_sel(vifp, ip) 1869 register struct vif *vifp; 1870 register struct ip *ip; 1871{ 1872 register int i; 1873 register int s = splnet(); 1874 register u_int p; 1875 1876 p = priority(vifp, ip); 1877 1878 for(i=vifp->v_tbf->q_len-1;i >= 0;i--) { 1879 if (p > priority(vifp, qtable[vifp-viftable][i].pkt_ip)) { 1880 m_freem(qtable[vifp-viftable][i].pkt_m); 1881 tbf_dequeue(vifp,i); 1882 splx(s); 1883 mrtstat.mrts_drop_sel++; 1884 return(1); 1885 } 1886 } 1887 splx(s); 1888 return(0); 1889} 1890 1891static void 1892tbf_send_packet(vifp, m, imo) 1893 register struct vif *vifp; 1894 register struct mbuf *m; 1895 struct ip_moptions *imo; 1896{ 1897 int error; 1898 int s = splnet(); 1899 1900 if (vifp->v_flags & VIFF_TUNNEL) { 1901 /* If tunnel options */ 1902 ip_output(m, (struct mbuf *)0, (struct route *)0, 1903 IP_FORWARDING, imo); 1904 } else { 1905 /* if physical interface option, extract the options and then send */ 1906 error = ip_output(m, (struct mbuf *)0, (struct route *)0, 1907 IP_FORWARDING, imo); 1908 FREE(imo, M_IPMOPTS); 1909 1910 if (mrtdebug & DEBUG_XMIT) 1911 log(LOG_DEBUG, "phyint_send on vif %d err %d", vifp-viftable, error); 1912 } 1913 splx(s); 1914} 1915 1916/* determine the current time and then 1917 * the elapsed time (between the last time and time now) 1918 * in milliseconds & update the no. of tokens in the bucket 1919 */ 1920static void 1921tbf_update_tokens(vifp) 1922 register struct vif *vifp; 1923{ 1924 struct timeval tp; 1925 register u_long t; 1926 register u_long elapsed; 1927 register int s = splnet(); 1928 1929 GET_TIME(tp); 1930 1931 t = tp.tv_sec*1000 + tp.tv_usec/1000; 1932 1933 elapsed = (t - vifp->v_tbf->last_pkt_t) * vifp->v_rate_limit /8; 1934 vifp->v_tbf->n_tok += elapsed; 1935 vifp->v_tbf->last_pkt_t = t; 1936 1937 if (vifp->v_tbf->n_tok > MAX_BKT_SIZE) 1938 vifp->v_tbf->n_tok = MAX_BKT_SIZE; 1939 1940 splx(s); 1941} 1942 1943static int 1944priority(vifp, ip) 1945 register struct vif *vifp; 1946 register struct ip *ip; 1947{ 1948 register int prio; 1949 1950 /* temporary hack; may add general packet classifier some day */ 1951 1952 /* 1953 * The UDP port space is divided up into four priority ranges: 1954 * [0, 16384) : unclassified - lowest priority 1955 * [16384, 32768) : audio - highest priority 1956 * [32768, 49152) : whiteboard - medium priority 1957 * [49152, 65536) : video - low priority 1958 */ 1959 if (ip->ip_p == IPPROTO_UDP) { 1960 struct udphdr *udp = (struct udphdr *)(((char *)ip) + (ip->ip_hl << 2)); 1961 switch (ntohs(udp->uh_dport) & 0xc000) { 1962 case 0x4000: 1963 prio = 70; 1964 break; 1965 case 0x8000: 1966 prio = 60; 1967 break; 1968 case 0xc000: 1969 prio = 55; 1970 break; 1971 default: 1972 prio = 50; 1973 break; 1974 } 1975 if (tbfdebug > 1) 1976 log(LOG_DEBUG, "port %x prio%d", ntohs(udp->uh_dport), prio); 1977 } else { 1978 prio = 50; 1979 } 1980 return prio; 1981} 1982 1983/* 1984 * End of token bucket filter modifications 1985 */ 1986 1987int 1988ip_rsvp_vif_init(so, m) 1989 struct socket *so; 1990 struct mbuf *m; 1991{ 1992 int i; 1993 register int s; 1994 1995 if (rsvpdebug) 1996 printf("ip_rsvp_vif_init: so_type = %d, pr_protocol = %d\n", 1997 so->so_type, so->so_proto->pr_protocol); 1998 1999 if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP) 2000 return EOPNOTSUPP; 2001 2002 /* Check mbuf. */ 2003 if (m == NULL || m->m_len != sizeof(int)) { 2004 return EINVAL; 2005 } 2006 i = *(mtod(m, int *)); 2007 2008 if (rsvpdebug) 2009 printf("ip_rsvp_vif_init: vif = %d rsvp_on = %d\n",i,rsvp_on); 2010 2011 s = splnet(); 2012 2013 /* Check vif. */ 2014 if (!legal_vif_num(i)) { 2015 splx(s); 2016 return EADDRNOTAVAIL; 2017 } 2018 2019 /* Check if socket is available. */ 2020 if (viftable[i].v_rsvpd != NULL) { 2021 splx(s); 2022 return EADDRINUSE; 2023 } 2024 2025 viftable[i].v_rsvpd = so; 2026 /* This may seem silly, but we need to be sure we don't over-increment 2027 * the RSVP counter, in case something slips up. 2028 */ 2029 if (!viftable[i].v_rsvp_on) { 2030 viftable[i].v_rsvp_on = 1; 2031 rsvp_on++; 2032 } 2033 2034 splx(s); 2035 return 0; 2036} 2037 2038int 2039ip_rsvp_vif_done(so, m) 2040 struct socket *so; 2041 struct mbuf *m; 2042{ 2043 int i; 2044 register int s; 2045 2046 if (rsvpdebug) 2047 printf("ip_rsvp_vif_done: so_type = %d, pr_protocol = %d\n", 2048 so->so_type, so->so_proto->pr_protocol); 2049 2050 if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP) 2051 return EOPNOTSUPP; 2052 2053 /* Check mbuf. */ 2054 if (m == NULL || m->m_len != sizeof(int)) { 2055 return EINVAL; 2056 } 2057 i = *(mtod(m, int *)); 2058 2059 s = splnet(); 2060 2061 /* Check vif. */ 2062 if (!legal_vif_num(i)) { 2063 splx(s); 2064 return EADDRNOTAVAIL; 2065 } 2066 2067 if (rsvpdebug) 2068 printf("ip_rsvp_vif_done: v_rsvpd = %x so = %x\n", 2069 viftable[i].v_rsvpd, so); 2070 2071 viftable[i].v_rsvpd = NULL; 2072 /* This may seem silly, but we need to be sure we don't over-decrement 2073 * the RSVP counter, in case something slips up. 2074 */ 2075 if (viftable[i].v_rsvp_on) { 2076 viftable[i].v_rsvp_on = 0; 2077 rsvp_on--; 2078 } 2079 2080 splx(s); 2081 return 0; 2082} 2083 2084void 2085ip_rsvp_force_done(so) 2086 struct socket *so; 2087{ 2088 int vifi; 2089 register int s; 2090 2091 /* Don't bother if it is not the right type of socket. */ 2092 if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP) 2093 return; 2094 2095 s = splnet(); 2096 2097 /* The socket may be attached to more than one vif...this 2098 * is perfectly legal. 2099 */ 2100 for (vifi = 0; vifi < numvifs; vifi++) { 2101 if (viftable[vifi].v_rsvpd == so) { 2102 viftable[vifi].v_rsvpd = NULL; 2103 /* This may seem silly, but we need to be sure we don't 2104 * over-decrement the RSVP counter, in case something slips up. 2105 */ 2106 if (viftable[vifi].v_rsvp_on) { 2107 viftable[vifi].v_rsvp_on = 0; 2108 rsvp_on--; 2109 } 2110 } 2111 } 2112 2113 splx(s); 2114 return; 2115} 2116 2117void 2118rsvp_input(m, ifp) 2119 struct mbuf *m; 2120 struct ifnet *ifp; 2121{ 2122 int vifi; 2123 register struct ip *ip = mtod(m, struct ip *); 2124 static struct sockaddr_in rsvp_src = { AF_INET }; 2125 register int s; 2126 2127 if (rsvpdebug) 2128 printf("rsvp_input: rsvp_on %d\n",rsvp_on); 2129 2130 /* Can still get packets with rsvp_on = 0 if there is a local member 2131 * of the group to which the RSVP packet is addressed. But in this 2132 * case we want to throw the packet away. 2133 */ 2134 if (!rsvp_on) { 2135 m_freem(m); 2136 return; 2137 } 2138 2139 /* If the old-style non-vif-associated socket is set, then use 2140 * it and ignore the new ones. 2141 */ 2142 if (ip_rsvpd != NULL) { 2143 if (rsvpdebug) 2144 printf("rsvp_input: Sending packet up old-style socket\n"); 2145 rip_input(m); 2146 return; 2147 } 2148 2149 s = splnet(); 2150 2151 if (rsvpdebug) 2152 printf("rsvp_input: check vifs\n"); 2153 2154 /* Find which vif the packet arrived on. */ 2155 for (vifi = 0; vifi < numvifs; vifi++) { 2156 if (viftable[vifi].v_ifp == ifp) 2157 break; 2158 } 2159 2160 if (vifi == numvifs) { 2161 /* Can't find vif packet arrived on. Drop packet. */ 2162 if (rsvpdebug) 2163 printf("rsvp_input: Can't find vif for packet...dropping it.\n"); 2164 m_freem(m); 2165 splx(s); 2166 return; 2167 } 2168 2169 if (rsvpdebug) 2170 printf("rsvp_input: check socket\n"); 2171 2172 if (viftable[vifi].v_rsvpd == NULL) { 2173 /* drop packet, since there is no specific socket for this 2174 * interface */ 2175 if (rsvpdebug) 2176 printf("rsvp_input: No socket defined for vif %d\n",vifi); 2177 m_freem(m); 2178 splx(s); 2179 return; 2180 } 2181 rsvp_src.sin_addr = ip->ip_src; 2182 2183 if (rsvpdebug && m) 2184 printf("rsvp_input: m->m_len = %d, sbspace() = %d\n", 2185 m->m_len,sbspace(&(viftable[vifi].v_rsvpd->so_rcv))); 2186 2187 if (socket_send(viftable[vifi].v_rsvpd, m, &rsvp_src) < 0) 2188 if (rsvpdebug) 2189 printf("rsvp_input: Failed to append to socket\n"); 2190 else 2191 if (rsvpdebug) 2192 printf("rsvp_input: send packet up\n"); 2193 2194 splx(s); 2195} 2196 2197#ifdef MROUTE_LKM 2198#include <sys/conf.h> 2199#include <sys/exec.h> 2200#include <sys/sysent.h> 2201#include <sys/lkm.h> 2202 2203MOD_MISC("ip_mroute_mod") 2204 2205static int 2206ip_mroute_mod_handle(struct lkm_table *lkmtp, int cmd) 2207{ 2208 int i; 2209 struct lkm_misc *args = lkmtp->private.lkm_misc; 2210 int err = 0; 2211 2212 switch(cmd) { 2213 static int (*old_ip_mrouter_cmd)(); 2214 static int (*old_ip_mrouter_done)(); 2215 static int (*old_ip_mforward)(); 2216 static int (*old_mrt_ioctl)(); 2217 static void (*old_proto4_input)(); 2218 static int (*old_legal_vif_num)(); 2219 extern struct protosw inetsw[]; 2220 2221 case LKM_E_LOAD: 2222 if(lkmexists(lkmtp) || ip_mrtproto) 2223 return(EEXIST); 2224 old_ip_mrouter_cmd = ip_mrouter_cmd; 2225 ip_mrouter_cmd = X_ip_mrouter_cmd; 2226 old_ip_mrouter_done = ip_mrouter_done; 2227 ip_mrouter_done = X_ip_mrouter_done; 2228 old_ip_mforward = ip_mforward; 2229 ip_mforward = X_ip_mforward; 2230 old_mrt_ioctl = mrt_ioctl; 2231 mrt_ioctl = X_mrt_ioctl; 2232 old_proto4_input = inetsw[ip_protox[ENCAP_PROTO]].pr_input; 2233 inetsw[ip_protox[ENCAP_PROTO]].pr_input = X_ipip_input; 2234 old_legal_vif_num = legal_vif_num; 2235 legal_vif_num = X_legal_vif_num; 2236 ip_mrtproto = IGMP_DVMRP; 2237 2238 printf("\nIP multicast routing loaded\n"); 2239 break; 2240 2241 case LKM_E_UNLOAD: 2242 if (ip_mrouter) 2243 return EINVAL; 2244 2245 ip_mrouter_cmd = old_ip_mrouter_cmd; 2246 ip_mrouter_done = old_ip_mrouter_done; 2247 ip_mforward = old_ip_mforward; 2248 mrt_ioctl = old_mrt_ioctl; 2249 inetsw[ip_protox[ENCAP_PROTO]].pr_input = old_proto4_input; 2250 legal_vif_num = old_legal_vif_num; 2251 ip_mrtproto = 0; 2252 break; 2253 2254 default: 2255 err = EINVAL; 2256 break; 2257 } 2258 2259 return(err); 2260} 2261 2262int 2263ip_mroute_mod(struct lkm_table *lkmtp, int cmd, int ver) { 2264 DISPATCH(lkmtp, cmd, ver, ip_mroute_mod_handle, ip_mroute_mod_handle, 2265 nosys); 2266} 2267 2268#endif /* MROUTE_LKM */ 2269#endif /* MROUTING */ 2270