OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [bsd_tcpip/] [v2_0/] [src/] [sys/] [netinet/] [ip_mroute.c] - Blame information for rev 174

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.