⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip_mroute.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        );		s = splnet();				if (mfccp->mfcc_origin.s_addr == 0) 		{/* updating a 0,g entry updates all s,g entries for that interface*/			rt->mfc_parent = mfccp->mfcc_parent;            MRTDEBUG            (                (mrtdebug & DEBUG_FORWARD),				"MROUTE: add_mfc updating all rts %p p %x, val=%x\n",                ntohl(mfccp->mfcc_mcastgrp.s_addr),                rt->mfc_parent,                 viftable[rt->mfc_parent].v_threshold,                4,5,6            );			if (mfccp->mfcc_ttls[rt->mfc_parent] != 0)				mRouteOifsAdd(rt, 					rt->mfc_parent, 					viftable[rt->mfc_parent].v_threshold);			else				mRouteOifsAdd(rt, rt->mfc_parent, 0);		}		else		{			for (i=0; i<numvifs; i++)			{/* an s,g add/update doesn't affect other entries*/				rt->mfc_parent = mfccp->mfcc_parent;			    MRTDEBUG                (                    (mrtdebug & DEBUG_FORWARD),					"MROUTE: add_mfc updating rts o=%p g=%p p %x, val=%x\n",					ntohl(rt->mfc_origin.s_addr),					ntohl(rt->mfc_mcastgrp.s_addr),					rt->mfc_parent,                     viftable[rt->mfc_parent].v_threshold,                    5,6                );				rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];			}			rt->mfc_notify = mfccp->mfcc_notify;		}        MRTDEBUG        (            (mrtdebug & DEBUG_MFC),			"MROUTE: add_mfc updated o %p g%p p%p, root_rt=%p.\n",			ntohl(mfccp->mfcc_origin.s_addr),			ntohl(mfccp->mfcc_mcastgrp.s_addr),			(u_long)rt->mfc_parent, 			(u_long)rt->mfc_root_rt,            5,6        );		splx(s);		return 0;    }    /*      * Find the entry for which the upcall was made and update     */    s = splnet();    hash = MFCHASH(mfccp->mfcc_origin.s_addr, mfccp->mfcc_mcastgrp.s_addr);    for (rt = mfctable[hash], nstl = 0; rt; rt = rt->mfc_next) 	{		if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) &&			(rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr) &&			(rt->mfc_stall != NULL)) 		{/* looking for entry with packet waiting on it */			if (nstl++)			{			    MRTDEBUG                (                    (mrtdebug), 				    "MROUTE: add_mfc multiple kernel entries \                    o %p g %p p %x dbx %p\n",					ntohl(mfccp->mfcc_origin.s_addr),					ntohl(mfccp->mfcc_mcastgrp.s_addr),					mfccp->mfcc_parent,                     (int)rt->mfc_stall,                    5,6                );			}            MRTDEBUG            (                (mrtdebug & DEBUG_MFC), 				"MROUTE: add_mfc o %p g %p p %x dbg %p\n",				ntohl(mfccp->mfcc_origin.s_addr),				ntohl(mfccp->mfcc_mcastgrp.s_addr),				mfccp->mfcc_parent,                 (int)rt->mfc_stall,                5,6            );			/* copy the information into rt entry */			rt->mfc_origin     = mfccp->mfcc_origin;			rt->mfc_mcastgrp   = mfccp->mfcc_mcastgrp;			rt->mfc_notify   = mfccp->mfcc_notify;			if (! (mfccp->mfcc_parent > numvifs) ) /* can't be less, it's a USHORT value */				rt->mfc_parent = mfccp->mfcc_parent;			if (mfccp->mfcc_origin.s_addr == 0)			{    		    MRTDEBUG                (                    (mrtdebug & DEBUG_FORWARD),					"MROUTE: add_mfc updating rts o=%p g=%p p %x, val=%x\n",                    ntohl(rt->mfc_origin.s_addr),					ntohl(rt->mfc_mcastgrp.s_addr),					rt->mfc_parent,                     viftable[rt->mfc_parent].v_threshold,                    5,6                );				mRouteOifsAdd(rt, rt->mfc_parent, viftable[rt->mfc_parent].v_threshold);			}/* update all routes for *,g entry add */			else for (i = 0; i < numvifs; i++)			{				if ( (mfccp->mfcc_origin.s_addr != 0)					&&(mfccp->mfcc_ttls[i] != 0)					)				{                    MRTDEBUG                    (                        (mrtdebug & DEBUG_FORWARD),						"MROUTE: add_mfc changing rt %p,%p vif %i to %i\n",                        ntohl(rt->mfc_origin.s_addr),						ntohl(rt->mfc_mcastgrp.s_addr),						i,                         viftable[i].v_threshold,                        5,6                    );					rt->mfc_ttls[i] = viftable[i].v_threshold;				}/* copy the oif list for s,g entries */			}			/* initialize pkt counters per src-grp */			rt->mfc_pkt_cnt    = 0;			rt->mfc_byte_cnt   = 0;			rt->mfc_wrong_if   = 0;			rt->mfc_last_assert = 0;            rt->mfc_last_assert = 0;			rt->mfc_expire = 0;	/* Don't clean this guy up */			nexpire[hash]--;			/* free packets Qed at the end of this entry */			for (rte = rt->mfc_stall; rte != NULL; ) 			{				struct rtdetq *n = rte->next;			    MRTDEBUG                (                    (mrtdebug & DEBUG_FORWARD),					"MROUTE: add_mfc add_mfc calls ip_mdq.\n",                    1,2,3,4,5,6                );				ip_mdq(rte->m, rte->ifp, rt, -1);                MRTDEBUG                (                    (mrtdebug & DEBUG_FORWARD),					"MROUTE: add_mfc add_mfc done calling ip_mdq.\n",                    1,2,3,4,5,6                );				m_freem(rte->m);				MRT_FREE((char*) rte);				rte = n;			}			rt->mfc_stall = NULL;		}/* dQing stall entries */    }/* for mfctable[hash] loop */    /*     * It is possible that an entry is being inserted without an upcall	 * This would be primarily found in s,g joins from an overlying protcol	 * e.g. PIM     */    if (nstl == 0) 	{        MRTDEBUG        (            (mrtdebug & DEBUG_MFC),		    "MROUTE: add_mfc no upcall h %lu o %lx g %lx p %x\n",            hash,             (u_long)ntohl(mfccp->mfcc_origin.s_addr),			(u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),			mfccp->mfcc_parent,            5,6        );		for (rt = mfctable[hash]; rt != NULL; rt = rt->mfc_next) 		{						if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) &&			(rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr)) {			for (i = 0; i < numvifs; i++)			{/* if the entry exists, copy the oiflist */				if (mfccp->mfcc_ttls[i] != 0)					rt->mfc_ttls[i] = viftable[i].v_threshold;				else 					rt->mfc_ttls[i] = 0;			}			/* initialize pkt counters per src-grp */			rt->mfc_pkt_cnt    = 0;			rt->mfc_byte_cnt   = 0;			rt->mfc_wrong_if   = 0;			rt->mfc_last_assert = 0;            rt->mfc_last_assert = 0;			if (rt->mfc_expire)				nexpire[hash]--;			rt->mfc_expire	   = 0;			}		}		if (rt == NULL) 		{			/* no upcall, so make a new entry */			rt = MRT_ALLOC(sizeof(struct mfc));			if (rt == NULL) {			splx(s);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */        WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 17, 1,                         WV_NETEVENT_ADDMRT_NOBUFS)#endif  /* INCLUDE_WVNET */#endif			return ENOBUFS;			}			rt->mfc_notify = 0;			rt->mfc_origin     = mfccp->mfcc_origin;			rt->mfc_mcastgrp   = mfccp->mfcc_mcastgrp;			/* link into hash chain now so the search for the root_rt will work */			rt->mfc_next = mfctable[hash];			mfctable[hash] = rt;			for (i = 0; i < numvifs; i++)			{				if (mfccp->mfcc_ttls[i] != 0)					rt->mfc_ttls[i] = viftable[i].v_threshold;				else 					rt->mfc_ttls[i] = 0;			}			/* find the *,g entry and link in */			MFCFIND(0, mfccp->mfcc_mcastgrp.s_addr, root_rt);			if (root_rt == NULL)			{				root_rt = MRT_ALLOC(sizeof(struct mfc));				if (root_rt == NULL) 				{					MRT_FREE((char*) rt);					splx(s);					return ENOBUFS;				}				root_rt->mfc_notify = 0;				/* inset NULL entry at head of hash chain */				root_rt->mfc_origin.s_addr     = 0;				root_rt->mfc_mcastgrp   = mfccp->mfcc_mcastgrp;				root_rt->mfc_parent     = 0;				for (i = 0; i < numvifs; i++)				{					root_rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];				}				/* initialize pkt counters per src-grp */				root_rt->mfc_pkt_cnt    = 0;				root_rt->mfc_byte_cnt   = 0;				root_rt->mfc_wrong_if   = 0;				root_rt->mfc_last_assert = 0;                rt->mfc_last_assert = 0;				root_rt->mfc_expire     = 0;				root_rt->mfc_stall      = NULL;				/* link *,g into table */				root_rt->mfc_next = 					mfctable[MFCHASH(root_rt->mfc_origin.s_addr, root_rt->mfc_mcastgrp.s_addr)];				mfctable[MFCHASH(root_rt->mfc_origin.s_addr, root_rt->mfc_mcastgrp.s_addr)] = root_rt;				root_rt->mfc_next_g = root_rt;	/* next group in same chain */				root_rt->mfc_root_rt = root_rt;	/* 0,g entry in hash table, itself in this case*/			}			rt->mfc_root_rt = root_rt;				/* insert into front of group chain*/			rt->mfc_next_g = root_rt->mfc_next_g;			root_rt->mfc_next_g = rt;    		if (!(mfccp->mfcc_parent > numvifs) )/* can't be less than 0, it's a USHORT */				rt->mfc_parent = mfccp->mfcc_parent;	/* take care of the details before you alter the forwarding state.  */			rt->mfc_pkt_cnt    = 0;			rt->mfc_byte_cnt   = 0;			rt->mfc_wrong_if   = 0;			rt->mfc_last_assert = 0;            rt->mfc_last_assert = 0;			rt->mfc_expire     = 0;			rt->mfc_stall      = NULL;		}/* rt == null */    }/* nstl == 0 */    splx(s);    return 0;}/*  * Resets the passed oif to 0 for a chain */static int mRouteOifsRemove    (    struct mfc* rt,     int oif    ){	struct mfc* probe;	if (rt == NULL)		return (EINVAL);		rt->mfc_root_rt->mfc_ttls[oif] = 0;		probe = rt->mfc_root_rt;        while (probe->mfc_next_g != probe->mfc_root_rt)    {   		probe = probe->mfc_next_g;		probe->mfc_ttls[oif] = 0;    }	return (OK);}/*  * Removes from the chain of all g entries */static intmRouteGroupLoopRemove    (    struct mfc* rt,     struct mfc* root    ){   	struct mfc* probe;	probe = root;    while (probe->mfc_next_g != probe->mfc_root_rt)    {   		probe = probe->mfc_next_g ;		if (probe->mfc_next_g == rt)			break;    }	if (probe->mfc_next_g == rt)	{		probe->mfc_next_g = rt->mfc_next_g ;	}	return (OK);}	 /* * Delete an mfc entry */static int	del_mfc(mfccp)    struct mfcctl *mfccp;{    struct in_addr 	origin;    struct in_addr 	mcastgrp;    struct mfc 		*rt;    struct mfc 		*root;	struct mfc	 	**nptr;    u_long 		hash;    int s;    origin = mfccp->mfcc_origin;    mcastgrp = mfccp->mfcc_mcastgrp;    hash = MFCHASH(origin.s_addr, mcastgrp.s_addr);    MRTDEBUG    (        (mrtdebug & DEBUG_MFC),		"MROUTE: del_mfc orig %lx mcastgrp %lx\n",        (u_long)ntohl(origin.s_addr),         (u_long)ntohl(mcastgrp.s_addr),        3,4,5,6    );    s = splnet();    nptr = &mfctable[hash];    while ((rt = *nptr) != NULL) 	{		if (origin.s_addr == rt->mfc_origin.s_addr &&			mcastgrp.s_addr == rt->mfc_mcastgrp.s_addr &&			rt->mfc_stall == NULL)			break;		nptr = &rt->mfc_next;    }    if (rt == NULL) 	{		splx(s);		return EADDRNOTAVAIL;    }	/* if *,g remove, remove all oifs from group chain */	if (rt->mfc_origin.s_addr == 0)		mRouteOifsRemove(rt, mfccp->mfcc_parent);	else	{		/* remove entry from group chain */			root = rt->mfc_root_rt;		mRouteGroupLoopRemove(rt, root);		*nptr = rt->mfc_next;/* removes from hash chain */		MRT_FREE((char*) rt);/* removes the s,g entry */		if ( (u_long)root->mfc_next_g == (u_long)root->mfc_root_rt == (u_long)root)		/* this is the only g entry in the table */		{			hash = MFCHASH(0, mcastgrp.s_addr);			nptr = &mfctable[hash];			while ((rt = *nptr) != NULL) 			{				if (origin.s_addr == rt->mfc_origin.s_addr &&					mcastgrp.s_addr == rt->mfc_mcastgrp.s_addr &&					rt->mfc_stall == NULL)					break;				nptr = &rt->mfc_next;			}			if (root == rt)			{				*nptr = rt->mfc_next;/* removes from hash chain */				MRT_FREE((char*) rt);/* frees up the 0,g entry */			}		}	}/* origin not == NULL */	splx(s);    return 0;}/******************************************************************************** mRouteGroupAdd - add a multicast group to the given interface** Adds the given group to the list of multicast groups on the given port.* Thus, multicast packets to that address will go out the port.** RETURNS: OK if successful, ERROR otherwise**/STATUS mRouteGroupAdd    (	struct ifnet* ifp,     struct in_addr srcAddr,       /* multicast source to add */    struct in_addr groupAddr      /* multicast group to add */    )    {	struct mfcctl gCtl;	int sockfd;	int port;    struct mfc *rt;	rt = NULL;		MFCFIND(0, groupAddr.s_addr, rt);	if (ifp == NULL)    {        return (ERROR);    }	port = mRouteNameToPort(ifp->if_name, ifp->if_unit);    if ( (port == ERROR) )        return (ERROR);    gCtl.mfcc_parent = port;                    /* ports are vifs for now */    gCtl.mfcc_mcastgrp = groupAddr;	gCtl.mfcc_origin = srcAddr;/* 0 for a star,g entry */	gCtl.mfcc_notify = 0;   /* mfcc_notify set to 0 so pimNotify never called */	if (rt != NULL)	{		memcpy(gCtl.mfcc_ttls, rt->mfc_ttls, numvifs);	}	else 	{		bzero (gCtl.mfcc_ttls, 32);	}	sockfd = (int)ip_mrouter;    if (sockfd <= 0)        return (ERROR);    MRTDEBUG    (        (mrtdebug & DEBUG_MFC),		"MROUTE: IP_MROUTER calling mfc_add.\n",        1,2,3,4,5,6    );	if (setsockopt (sockfd, IPPROTO_IP, MRT_ADD_MFC,                   (char *) &gCtl, sizeof(gCtl)) == ERROR)    {	    MRTDEBUG        (            (mrtdebug),		    "MROUTE: igmpGroupAdd failed with errno: %d",            errno,2,3,4,5,6        );               return ERROR;    }	return (OK);}/******************************************************************************** pimNotify - notifies pim daemon about new packet on an interface** RETURNS: OK for success, ERROR for failure**/static int pimNotify    (    struct ip * pIp,     struct mbuf* pMbuf,     struct mfc* pRt,    vifi_t vifi,     struct ifnet* pIfnet    ){	    struct sockaddr_in k_igmpsrc;	    struct mbuf *pMbufCopy;	    struct igmpmsg *pIGMPMessage;		struct ip * pIpNew;	    UINT now;		int hlen;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -