ip6_del_rt(rt, NULL, NULL); 
ip6_del_rt(rt, NULL, NULL, NULL); 
static void ndisc_router_discovery(struct sk_buff *skb){        struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;	struct neighbour *neigh = NULL;	struct inet6_dev *in6_dev;	struct rt6_info *rt;	int lifetime;	struct ndisc_options ndopts;	int optlen;	__u8 * opt = (__u8 *)(ra_msg + 1);	optlen = (skb->tail - skb->h.raw) - sizeof(struct ra_msg);	if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr) & IPV6_ADDR_LINKLOCAL)) {		ND_PRINTK2(KERN_WARNING			   "ICMPv6 RA: source address is not link-local.\n");		return;	}	if (optlen < 0) {		ND_PRINTK2(KERN_WARNING 			   "ICMPv6 RA: packet too short\n");		return;	}	/*	 *	set the RA_RECV flag in the interface	 */	in6_dev = in6_dev_get(skb->dev);	if (in6_dev == NULL) {		ND_PRINTK0(KERN_ERR			   "ICMPv6 RA: can't find inet6 device for %s.\n",			   skb->dev->name);		return;	}	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {		in6_dev_put(in6_dev);		return;	}	if (!ndisc_parse_options(opt, optlen, &ndopts)) {		in6_dev_put(in6_dev);		ND_PRINTK2(KERN_WARNING			   "ICMP6 RA: invalid ND options\n");		return;	}	if (in6_dev->if_flags & IF_RS_SENT) {		/*		 *	flag that an RA was received after an RS was sent		 *	out on this interface.		 */		in6_dev->if_flags |= IF_RA_RCVD;	}	/*	 * Remember the managed/otherconf flags from most recently	 * received RA message (RFC 2462) -- yoshfuji	 */	in6_dev->if_flags = (in6_dev->if_flags & ~(IF_RA_MANAGED |				IF_RA_OTHERCONF)) |				(ra_msg->icmph.icmp6_addrconf_managed ?					IF_RA_MANAGED : 0) |				(ra_msg->icmph.icmp6_addrconf_other ?					IF_RA_OTHERCONF : 0);	lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);	rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);	if (rt)		neigh = rt->rt6i_nexthop;	if (rt && lifetime == 0) {		neigh_clone(neigh);		ip6_del_rt(rt, NULL, NULL);		rt = NULL;	}	if (rt == NULL && lifetime) {		ND_PRINTK3(KERN_DEBUG			   "ICMPv6 RA: adding default router.\n");		rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);		if (rt == NULL) {			ND_PRINTK0(KERN_ERR				   "ICMPv6 RA: %s() failed to add default route.\n",				   __FUNCTION__);			in6_dev_put(in6_dev);			return;		}		neigh = rt->rt6i_nexthop;		if (neigh == NULL) {			ND_PRINTK0(KERN_ERR				   "ICMPv6 RA: %s() got default router without neighbour.\n",				   __FUNCTION__);			dst_release(&rt->u.dst);			in6_dev_put(in6_dev);			return;		}		neigh->flags |= NTF_ROUTER;	}	if (rt)		rt->rt6i_expires = jiffies + (HZ * lifetime);	if (ra_msg->icmph.icmp6_hop_limit) {		in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;		if (rt)			rt->u.dst.metrics[RTAX_HOPLIMIT-1] = ra_msg->icmph.icmp6_hop_limit;	}	/*	 *	Update Reachable Time and Retrans Timer	 */	if (in6_dev->nd_parms) {		unsigned long rtime = ntohl(ra_msg->retrans_timer);		if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/HZ) {			rtime = (rtime*HZ)/1000;			if (rtime < HZ/10)				rtime = HZ/10;			in6_dev->nd_parms->retrans_time = rtime;			in6_dev->tstamp = jiffies;			inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);		}		rtime = ntohl(ra_msg->reachable_time);		if (rtime && rtime/1000 < MAX_SCHEDULE_TIMEOUT/(3*HZ)) {			rtime = (rtime*HZ)/1000;			if (rtime < HZ/10)				rtime = HZ/10;			if (rtime != in6_dev->nd_parms->base_reachable_time) {				in6_dev->nd_parms->base_reachable_time = rtime;				in6_dev->nd_parms->gc_staletime = 3 * rtime;				in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime);				in6_dev->tstamp = jiffies;				inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);			}		}	}	/*	 *	Process options.	 */	if (!neigh)		neigh = __neigh_lookup(&nd_tbl, &skb->nh.ipv6h->saddr,				       skb->dev, 1);	if (neigh) {		u8 *lladdr = NULL;		if (ndopts.nd_opts_src_lladdr) {			lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr,						     skb->dev);			if (!lladdr) {				ND_PRINTK2(KERN_WARNING					   "ICMPv6 RA: invalid link-layer address length\n");				goto out;			}		}		neigh_update(neigh, lladdr, NUD_STALE,			     NEIGH_UPDATE_F_WEAK_OVERRIDE|			     NEIGH_UPDATE_F_OVERRIDE|			     NEIGH_UPDATE_F_OVERRIDE_ISROUTER|			     NEIGH_UPDATE_F_ISROUTER);	}	if (ndopts.nd_opts_pi) {		struct nd_opt_hdr *p;		for (p = ndopts.nd_opts_pi;		     p;		     p = ndisc_next_option(p, ndopts.nd_opts_pi_end)) {			addrconf_prefix_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3);		}	}	if (ndopts.nd_opts_mtu) {		u32 mtu;		memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));		mtu = ntohl(mtu);		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {			ND_PRINTK2(KERN_WARNING				   "ICMPv6 RA: invalid mtu: %d\n",				   mtu);		} else if (in6_dev->cnf.mtu6 != mtu) {			in6_dev->cnf.mtu6 = mtu;			if (rt)				rt->u.dst.metrics[RTAX_MTU-1] = mtu;			rt6_mtu_change(skb->dev, mtu);		}	}				if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {		ND_PRINTK2(KERN_WARNING			   "ICMPv6 RA: invalid RA options");	}out:	if (rt)		dst_release(&rt->u.dst);	else if (neigh)		neigh_release(neigh);	in6_dev_put(in6_dev);}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/0d51aa80a9b1db43920c0770c3bb842dd823c005/ndisc.c/buggy/net/ipv6/ndisc.c