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

Cache object: 07db57bcab46bc22638ea25c44991b89


[ 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.