The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/ip_mroute.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 8325ef46a2b0a4f61cc1e887ca6c81c2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.