[BACK]Return to ip6_forward.c CVS log [TXT][DIR] Up to [local] / sys / netinet6

Annotation of sys/netinet6/ip6_forward.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ip6_forward.c,v 1.39 2007/06/01 00:52:38 henning Exp $        */
                      2: /*     $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $    */
                      3:
                      4: /*
                      5:  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. Neither the name of the project nor the names of its contributors
                     17:  *    may be used to endorse or promote products derived from this software
                     18:  *    without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
                     21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
                     24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     30:  * SUCH DAMAGE.
                     31:  */
                     32:
                     33: #include "pf.h"
                     34:
                     35: #include <sys/param.h>
                     36: #include <sys/systm.h>
                     37: #include <sys/malloc.h>
                     38: #include <sys/mbuf.h>
                     39: #include <sys/domain.h>
                     40: #include <sys/protosw.h>
                     41: #include <sys/socket.h>
                     42: #include <sys/errno.h>
                     43: #include <sys/time.h>
                     44: #include <sys/kernel.h>
                     45: #include <sys/syslog.h>
                     46:
                     47: #include <net/if.h>
                     48: #include <net/route.h>
                     49:
                     50: #include <netinet/in.h>
                     51: #include <netinet/in_var.h>
                     52: #include <netinet/ip_var.h>
                     53: #include <netinet/ip6.h>
                     54: #include <netinet6/ip6_var.h>
                     55: #include <netinet/icmp6.h>
                     56: #include <netinet6/nd6.h>
                     57:
                     58: #if NPF > 0
                     59: #include <net/pfvar.h>
                     60: #endif
                     61:
                     62: #ifdef IPSEC
                     63: #include <netinet/ip_ipsp.h>
                     64: #include <netinet/ip_ah.h>
                     65: #include <netinet/ip_esp.h>
                     66: #include <netinet/udp.h>
                     67: #include <netinet/tcp.h>
                     68: #include <net/pfkeyv2.h>
                     69: #endif
                     70:
                     71: struct route_in6 ip6_forward_rt;
                     72: int    ip6_forward_rtableid;
                     73:
                     74: /*
                     75:  * Forward a packet.  If some error occurs return the sender
                     76:  * an icmp packet.  Note we can't always generate a meaningful
                     77:  * icmp message because icmp doesn't have a large enough repertoire
                     78:  * of codes and types.
                     79:  *
                     80:  * If not forwarding, just drop the packet.  This could be confusing
                     81:  * if ipforwarding was zero but some routing protocol was advancing
                     82:  * us as a gateway to somewhere.  However, we must let the routing
                     83:  * protocol deal with that.
                     84:  *
                     85:  */
                     86:
                     87: void
                     88: ip6_forward(m, srcrt)
                     89:        struct mbuf *m;
                     90:        int srcrt;
                     91: {
                     92:        struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
                     93:        struct sockaddr_in6 *dst;
                     94:        struct rtentry *rt;
                     95:        int error = 0, type = 0, code = 0;
                     96:        struct mbuf *mcopy = NULL;
                     97:        struct ifnet *origifp;  /* maybe unnecessary */
                     98: #ifdef IPSEC
                     99:        u_int8_t sproto = 0;
                    100:        struct m_tag *mtag;
                    101:        union sockaddr_union sdst;
                    102:        struct tdb_ident *tdbi;
                    103:        u_int32_t sspi;
                    104:        struct tdb *tdb;
                    105:        int s;
                    106: #endif /* IPSEC */
                    107:        int rtableid = 0;
                    108:
                    109:        /*
                    110:         * Do not forward packets to multicast destination (should be handled
                    111:         * by ip6_mforward().
                    112:         * Do not forward packets with unspecified source.  It was discussed
                    113:         * in July 2000, on ipngwg mailing list.
                    114:         */
                    115:        if ((m->m_flags & (M_BCAST|M_MCAST)) != 0 ||
                    116:            IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
                    117:            IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
                    118:                ip6stat.ip6s_cantforward++;
                    119:                /* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
                    120:                if (ip6_log_time + ip6_log_interval < time_second) {
                    121:                        ip6_log_time = time_second;
                    122:                        log(LOG_DEBUG,
                    123:                            "cannot forward "
                    124:                            "from %s to %s nxt %d received on %s\n",
                    125:                            ip6_sprintf(&ip6->ip6_src),
                    126:                            ip6_sprintf(&ip6->ip6_dst),
                    127:                            ip6->ip6_nxt,
                    128:                            m->m_pkthdr.rcvif->if_xname);
                    129:                }
                    130:                m_freem(m);
                    131:                return;
                    132:        }
                    133:
                    134:        if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
                    135:                /* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
                    136:                icmp6_error(m, ICMP6_TIME_EXCEEDED,
                    137:                                ICMP6_TIME_EXCEED_TRANSIT, 0);
                    138:                return;
                    139:        }
                    140:        ip6->ip6_hlim -= IPV6_HLIMDEC;
                    141:
                    142: #ifdef IPSEC
                    143:        if (!ipsec_in_use)
                    144:                goto done_spd;
                    145:
                    146:        s = splnet();
                    147:
                    148:        /*
                    149:         * Check if there was an outgoing SA bound to the flow
                    150:         * from a transport protocol.
                    151:         */
                    152:
                    153:        /* Do we have any pending SAs to apply ? */
                    154:        mtag = m_tag_find(m, PACKET_TAG_IPSEC_PENDING_TDB, NULL);
                    155:        if (mtag != NULL) {
                    156: #ifdef DIAGNOSTIC
                    157:                if (mtag->m_tag_len != sizeof (struct tdb_ident))
                    158:                        panic("ip6_forward: tag of length %d (should be %d",
                    159:                            mtag->m_tag_len, sizeof (struct tdb_ident));
                    160: #endif
                    161:                tdbi = (struct tdb_ident *)(mtag + 1);
                    162:                tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
                    163:                if (tdb == NULL)
                    164:                        error = -EINVAL;
                    165:                m_tag_delete(m, mtag);
                    166:        } else
                    167:                tdb = ipsp_spd_lookup(m, AF_INET6, sizeof(struct ip6_hdr),
                    168:                    &error, IPSP_DIRECTION_OUT, NULL, NULL);
                    169:
                    170:        if (tdb == NULL) {
                    171:                splx(s);
                    172:
                    173:                if (error == 0) {
                    174:                        /*
                    175:                         * No IPsec processing required, we'll just send the
                    176:                         * packet out.
                    177:                         */
                    178:                        sproto = 0;
                    179:
                    180:                        /* Fall through to routing/multicast handling */
                    181:                } else {
                    182:                        /*
                    183:                         * -EINVAL is used to indicate that the packet should
                    184:                         * be silently dropped, typically because we've asked
                    185:                         * key management for an SA.
                    186:                         */
                    187:                        if (error == -EINVAL) /* Should silently drop packet */
                    188:                                error = 0;
                    189:
                    190:                        goto freecopy;
                    191:                }
                    192:        } else {
                    193:                /* Loop detection */
                    194:                for (mtag = m_tag_first(m); mtag != NULL;
                    195:                    mtag = m_tag_next(m, mtag)) {
                    196:                        if (mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_DONE &&
                    197:                            mtag->m_tag_id !=
                    198:                            PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED)
                    199:                                continue;
                    200:                        tdbi = (struct tdb_ident *)(mtag + 1);
                    201:                        if (tdbi->spi == tdb->tdb_spi &&
                    202:                            tdbi->proto == tdb->tdb_sproto &&
                    203:                            !bcmp(&tdbi->dst, &tdb->tdb_dst,
                    204:                            sizeof(union sockaddr_union))) {
                    205:                                splx(s);
                    206:                                sproto = 0; /* mark as no-IPsec-needed */
                    207:                                goto done_spd;
                    208:                        }
                    209:                }
                    210:
                    211:                /* We need to do IPsec */
                    212:                bcopy(&tdb->tdb_dst, &sdst, sizeof(sdst));
                    213:                sspi = tdb->tdb_spi;
                    214:                sproto = tdb->tdb_sproto;
                    215:                splx(s);
                    216:        }
                    217:
                    218:        /* Fall through to the routing/multicast handling code */
                    219:  done_spd:
                    220: #endif /* IPSEC */
                    221:
                    222: #if NPF > 0
                    223:        rtableid = m->m_pkthdr.pf.rtableid;
                    224: #endif
                    225:
                    226:        /*
                    227:         * Save at most ICMPV6_PLD_MAXLEN (= the min IPv6 MTU -
                    228:         * size of IPv6 + ICMPv6 headers) bytes of the packet in case
                    229:         * we need to generate an ICMP6 message to the src.
                    230:         * Thanks to M_EXT, in most cases copy will not occur.
                    231:         *
                    232:         * It is important to save it before IPsec processing as IPsec
                    233:         * processing may modify the mbuf.
                    234:         */
                    235:        mcopy = m_copy(m, 0, imin(m->m_pkthdr.len, ICMPV6_PLD_MAXLEN));
                    236:
                    237:        dst = &ip6_forward_rt.ro_dst;
                    238:        if (!srcrt) {
                    239:                /*
                    240:                 * ip6_forward_rt.ro_dst.sin6_addr is equal to ip6->ip6_dst
                    241:                 */
                    242:                if (ip6_forward_rt.ro_rt == 0 ||
                    243:                    (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) == 0 ||
                    244:                    ip6_forward_rtableid != rtableid) {
                    245:                        if (ip6_forward_rt.ro_rt) {
                    246:                                RTFREE(ip6_forward_rt.ro_rt);
                    247:                                ip6_forward_rt.ro_rt = 0;
                    248:                        }
                    249:                        /* this probably fails but give it a try again */
                    250:                        rtalloc_mpath((struct route *)&ip6_forward_rt,
                    251:                            &ip6->ip6_src.s6_addr32[0], rtableid);
                    252:                        ip6_forward_rtableid = rtableid;
                    253:                }
                    254:
                    255:                if (ip6_forward_rt.ro_rt == 0) {
                    256:                        ip6stat.ip6s_noroute++;
                    257:                        /* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_noroute) */
                    258:                        if (mcopy) {
                    259:                                icmp6_error(mcopy, ICMP6_DST_UNREACH,
                    260:                                            ICMP6_DST_UNREACH_NOROUTE, 0);
                    261:                        }
                    262:                        m_freem(m);
                    263:                        return;
                    264:                }
                    265:        } else if ((rt = ip6_forward_rt.ro_rt) == 0 ||
                    266:                 !IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst->sin6_addr)) {
                    267:                if (ip6_forward_rt.ro_rt) {
                    268:                        RTFREE(ip6_forward_rt.ro_rt);
                    269:                        ip6_forward_rt.ro_rt = 0;
                    270:                }
                    271:                bzero(dst, sizeof(*dst));
                    272:                dst->sin6_len = sizeof(struct sockaddr_in6);
                    273:                dst->sin6_family = AF_INET6;
                    274:                dst->sin6_addr = ip6->ip6_dst;
                    275:
                    276:                rtalloc_mpath((struct route *)&ip6_forward_rt,
                    277:                    &ip6->ip6_src.s6_addr32[0], 0);
                    278:
                    279:                if (ip6_forward_rt.ro_rt == 0) {
                    280:                        ip6stat.ip6s_noroute++;
                    281:                        /* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_noroute) */
                    282:                        if (mcopy) {
                    283:                                icmp6_error(mcopy, ICMP6_DST_UNREACH,
                    284:                                            ICMP6_DST_UNREACH_NOROUTE, 0);
                    285:                        }
                    286:                        m_freem(m);
                    287:                        return;
                    288:                }
                    289:        }
                    290:        rt = ip6_forward_rt.ro_rt;
                    291:
                    292:        /*
                    293:         * Scope check: if a packet can't be delivered to its destination
                    294:         * for the reason that the destination is beyond the scope of the
                    295:         * source address, discard the packet and return an icmp6 destination
                    296:         * unreachable error with Code 2 (beyond scope of source address).
                    297:         * [draft-ietf-ipngwg-icmp-v3-00.txt, Section 3.1]
                    298:         */
                    299:        if (in6_addr2scopeid(m->m_pkthdr.rcvif, &ip6->ip6_src) !=
                    300:            in6_addr2scopeid(rt->rt_ifp, &ip6->ip6_src)) {
                    301:                ip6stat.ip6s_cantforward++;
                    302:                ip6stat.ip6s_badscope++;
                    303:                in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard);
                    304:
                    305:                if (ip6_log_time + ip6_log_interval < time_second) {
                    306:                        ip6_log_time = time_second;
                    307:                        log(LOG_DEBUG,
                    308:                            "cannot forward "
                    309:                            "src %s, dst %s, nxt %d, rcvif %s, outif %s\n",
                    310:                            ip6_sprintf(&ip6->ip6_src),
                    311:                            ip6_sprintf(&ip6->ip6_dst),
                    312:                            ip6->ip6_nxt,
                    313:                            m->m_pkthdr.rcvif->if_xname, rt->rt_ifp->if_xname);
                    314:                }
                    315:                if (mcopy)
                    316:                        icmp6_error(mcopy, ICMP6_DST_UNREACH,
                    317:                                    ICMP6_DST_UNREACH_BEYONDSCOPE, 0);
                    318:                m_freem(m);
                    319:                goto freert;
                    320:        }
                    321:
                    322: #ifdef IPSEC
                    323:        /*
                    324:         * Check if the packet needs encapsulation.
                    325:         * ipsp_process_packet will never come back to here.
                    326:         * XXX ipsp_process_packet() calls ip6_output(), and there'll be no
                    327:         * PMTU notification.  is it okay?
                    328:         */
                    329:        if (sproto != 0) {
                    330:                s = splnet();
                    331:
                    332:                tdb = gettdb(sspi, &sdst, sproto);
                    333:                if (tdb == NULL) {
                    334:                        splx(s);
                    335:                        error = EHOSTUNREACH;
                    336:                        m_freem(m);
                    337:                        goto senderr;   /*XXX*/
                    338:                }
                    339:
                    340:                m->m_flags &= ~(M_BCAST | M_MCAST);     /* just in case */
                    341:
                    342:                /* Callee frees mbuf */
                    343:                error = ipsp_process_packet(m, tdb, AF_INET6, 0);
                    344:                splx(s);
                    345:                m_freem(mcopy);
                    346:                goto freert;
                    347:        }
                    348: #endif /* IPSEC */
                    349:
                    350:        if (m->m_pkthdr.len > IN6_LINKMTU(rt->rt_ifp)) {
                    351:                in6_ifstat_inc(rt->rt_ifp, ifs6_in_toobig);
                    352:                if (mcopy) {
                    353:                        u_long mtu;
                    354:
                    355:                        mtu = IN6_LINKMTU(rt->rt_ifp);
                    356:
                    357:                        icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0, mtu);
                    358:                }
                    359:                m_freem(m);
                    360:                goto freert;
                    361:        }
                    362:
                    363:        if (rt->rt_flags & RTF_GATEWAY)
                    364:                dst = (struct sockaddr_in6 *)rt->rt_gateway;
                    365:
                    366:        /*
                    367:         * If we are to forward the packet using the same interface
                    368:         * as one we got the packet from, perhaps we should send a redirect
                    369:         * to sender to shortcut a hop.
                    370:         * Only send redirect if source is sending directly to us,
                    371:         * and if packet was not source routed (or has any options).
                    372:         * Also, don't send redirect if forwarding using a route
                    373:         * modified by a redirect.
                    374:         */
                    375:        if (rt->rt_ifp == m->m_pkthdr.rcvif && !srcrt && ip6_sendredirects &&
                    376:            (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) {
                    377:                if ((rt->rt_ifp->if_flags & IFF_POINTOPOINT) &&
                    378:                    nd6_is_addr_neighbor((struct sockaddr_in6 *)&ip6_forward_rt.ro_dst, rt->rt_ifp)) {
                    379:                        /*
                    380:                         * If the incoming interface is equal to the outgoing
                    381:                         * one, the link attached to the interface is
                    382:                         * point-to-point, and the IPv6 destination is
                    383:                         * regarded as on-link on the link, then it will be
                    384:                         * highly probable that the destination address does
                    385:                         * not exist on the link and that the packet is going
                    386:                         * to loop.  Thus, we immediately drop the packet and
                    387:                         * send an ICMPv6 error message.
                    388:                         * For other routing loops, we dare to let the packet
                    389:                         * go to the loop, so that a remote diagnosing host
                    390:                         * can detect the loop by traceroute.
                    391:                         * type/code is based on suggestion by Rich Draves.
                    392:                         * not sure if it is the best pick.
                    393:                         */
                    394:                        icmp6_error(mcopy, ICMP6_DST_UNREACH,
                    395:                                    ICMP6_DST_UNREACH_ADDR, 0);
                    396:                        m_freem(m);
                    397:                        goto freert;
                    398:                }
                    399:                type = ND_REDIRECT;
                    400:        }
                    401:
                    402:        /*
                    403:         * Fake scoped addresses. Note that even link-local source or
                    404:         * destinaion can appear, if the originating node just sends the
                    405:         * packet to us (without address resolution for the destination).
                    406:         * Since both icmp6_error and icmp6_redirect_output fill the embedded
                    407:         * link identifiers, we can do this stuff after making a copy for
                    408:         * returning an error.
                    409:         */
                    410:        if ((rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
                    411:                /*
                    412:                 * See corresponding comments in ip6_output.
                    413:                 * XXX: but is it possible that ip6_forward() sends a packet
                    414:                 *      to a loopback interface? I don't think so, and thus
                    415:                 *      I bark here. (jinmei@kame.net)
                    416:                 * XXX: it is common to route invalid packets to loopback.
                    417:                 *      also, the codepath will be visited on use of ::1 in
                    418:                 *      rthdr. (itojun)
                    419:                 */
                    420: #if 1
                    421:                if (0)
                    422: #else
                    423:                if ((rt->rt_flags & (RTF_BLACKHOLE|RTF_REJECT)) == 0)
                    424: #endif
                    425:                {
                    426:                        printf("ip6_forward: outgoing interface is loopback. "
                    427:                               "src %s, dst %s, nxt %d, rcvif %s, outif %s\n",
                    428:                               ip6_sprintf(&ip6->ip6_src),
                    429:                               ip6_sprintf(&ip6->ip6_dst),
                    430:                               ip6->ip6_nxt, m->m_pkthdr.rcvif->if_xname,
                    431:                               rt->rt_ifp->if_xname);
                    432:                }
                    433:
                    434:                /* we can just use rcvif in forwarding. */
                    435:                origifp = m->m_pkthdr.rcvif;
                    436:        }
                    437:        else
                    438:                origifp = rt->rt_ifp;
                    439:        if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
                    440:                ip6->ip6_src.s6_addr16[1] = 0;
                    441:        if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
                    442:                ip6->ip6_dst.s6_addr16[1] = 0;
                    443:
                    444: #if NPF > 0
                    445:        if (pf_test6(PF_OUT, rt->rt_ifp, &m, NULL) != PF_PASS) {
                    446:                m_freem(m);
                    447:                goto senderr;
                    448:        }
                    449:        if (m == NULL)
                    450:                goto senderr;
                    451:
                    452:        ip6 = mtod(m, struct ip6_hdr *);
                    453: #endif
                    454:
                    455:        error = nd6_output(rt->rt_ifp, origifp, m, dst, rt);
                    456:        if (error) {
                    457:                in6_ifstat_inc(rt->rt_ifp, ifs6_out_discard);
                    458:                ip6stat.ip6s_cantforward++;
                    459:        } else {
                    460:                ip6stat.ip6s_forward++;
                    461:                in6_ifstat_inc(rt->rt_ifp, ifs6_out_forward);
                    462:                if (type)
                    463:                        ip6stat.ip6s_redirectsent++;
                    464:                else {
                    465:                        if (mcopy)
                    466:                                goto freecopy;
                    467:                }
                    468:        }
                    469:
                    470: #if NPF > 0 || defined(IPSEC)
                    471: senderr:
                    472: #endif
                    473:        if (mcopy == NULL)
                    474:                goto freert;
                    475:        switch (error) {
                    476:        case 0:
                    477:                if (type == ND_REDIRECT) {
                    478:                        icmp6_redirect_output(mcopy, rt);
                    479:                        goto freert;
                    480:                }
                    481:                goto freecopy;
                    482:
                    483:        case EMSGSIZE:
                    484:                /* xxx MTU is constant in PPP? */
                    485:                goto freecopy;
                    486:
                    487:        case ENOBUFS:
                    488:                /* Tell source to slow down like source quench in IP? */
                    489:                goto freecopy;
                    490:
                    491:        case ENETUNREACH:       /* shouldn't happen, checked above */
                    492:        case EHOSTUNREACH:
                    493:        case ENETDOWN:
                    494:        case EHOSTDOWN:
                    495:        default:
                    496:                type = ICMP6_DST_UNREACH;
                    497:                code = ICMP6_DST_UNREACH_ADDR;
                    498:                break;
                    499:        }
                    500:        icmp6_error(mcopy, type, code, 0);
                    501:        goto freert;
                    502:
                    503:  freecopy:
                    504:        m_freem(mcopy);
                    505:  freert:
                    506: #ifndef SMALL_KERNEL
                    507:        if (ip6_multipath && ip6_forward_rt.ro_rt &&
                    508:            (ip6_forward_rt.ro_rt->rt_flags & RTF_MPATH)) {
                    509:                RTFREE(ip6_forward_rt.ro_rt);
                    510:                ip6_forward_rt.ro_rt = 0;
                    511:        }
                    512: #endif
                    513:        return;
                    514: }

CVSweb