Massive cleanup of the ip_mroute code.
No functional changes, but: + the mrouting module now should behave the same as the compiled-in version (it did not before, some of the rsvp code was not loaded properly); + netinet/ip_mroute.c is now truly optional; + removed some redundant/unused code; + changed many instances of '0' to NULL and INADDR_ANY as appropriate; + removed several static variables to make the code more SMP-friendly; + fixed some minor bugs in the mrouting code (mostly, incorrect return values from functions). This commit is also a prerequisite to the addition of support for PIM, which i would like to put in before DP2 (it does not change any of the existing APIs, anyways). Note, in the process we found out that some device drivers fail to properly handle changes in IFF_ALLMULTI, leading to interesting behaviour when a multicast router is started. This bug is not corrected by this commit, and will be fixed with a separate commit. Detailed changes: -------------------- netinet/ip_mroute.c all the above. conf/files make ip_mroute.c optional net/route.c fix mrt_ioctl hook netinet/ip_input.c fix ip_mforward hook, move rsvp_input() here together with other rsvp code, and a couple of indentation fixes. netinet/ip_output.c fix ip_mforward and ip_mcast_src hooks netinet/ip_var.h rsvp function hooks netinet/raw_ip.c hooks for mrouting and rsvp functions, plus interface cleanup. netinet/ip_mroute.h remove an unused and optional field from a struct Most of the code is from Pavlin Radoslavov and the XORP project Reviewed by: sam MFC after: 1 week
This commit is contained in:
parent
4001ea8d00
commit
bbb4330b61
@ -1318,7 +1318,7 @@ netinet/ip_flow.c optional inet
|
||||
netinet/ip_fw2.c optional ipfirewall
|
||||
netinet/ip_icmp.c optional inet
|
||||
netinet/ip_input.c optional inet
|
||||
netinet/ip_mroute.c optional inet
|
||||
netinet/ip_mroute.c optional mrouting
|
||||
netinet/ip_output.c optional inet
|
||||
netinet/raw_ip.c optional inet
|
||||
netinet/tcp_debug.c optional tcpdebug
|
||||
|
@ -403,7 +403,7 @@ rtioctl(req, data)
|
||||
{
|
||||
#ifdef INET
|
||||
/* Multicast goop, grrr... */
|
||||
return mrt_ioctl(req, data);
|
||||
return mrt_ioctl ? mrt_ioctl(req, data) : EOPNOTSUPP;
|
||||
#else /* INET */
|
||||
return ENXIO;
|
||||
#endif /* INET */
|
||||
|
@ -600,7 +600,8 @@ ip_input(struct mbuf *m)
|
||||
* ip_mforward() returns a non-zero value, the packet
|
||||
* must be discarded, else it may be accepted below.
|
||||
*/
|
||||
if (ip_mforward(ip, m->m_pkthdr.rcvif, m, 0) != 0) {
|
||||
if (ip_mforward &&
|
||||
ip_mforward(ip, m->m_pkthdr.rcvif, m, 0) != 0) {
|
||||
ipstat.ips_cantforward++;
|
||||
m_freem(m);
|
||||
return;
|
||||
@ -2073,10 +2074,10 @@ ip_rsvp_init(struct socket *so)
|
||||
{
|
||||
if (so->so_type != SOCK_RAW ||
|
||||
so->so_proto->pr_protocol != IPPROTO_RSVP)
|
||||
return EOPNOTSUPP;
|
||||
return EOPNOTSUPP;
|
||||
|
||||
if (ip_rsvpd != NULL)
|
||||
return EADDRINUSE;
|
||||
return EADDRINUSE;
|
||||
|
||||
ip_rsvpd = so;
|
||||
/*
|
||||
@ -2105,3 +2106,29 @@ ip_rsvp_done(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rsvp_input(struct mbuf *m, int off) /* XXX must fixup manually */
|
||||
{
|
||||
if (rsvp_input_p) { /* call the real one if loaded */
|
||||
rsvp_input_p(m, off);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Can still get packets with rsvp_on = 0 if there is a local member
|
||||
* of the group to which the RSVP packet is addressed. But in this
|
||||
* case we want to throw the packet away.
|
||||
*/
|
||||
|
||||
if (!rsvp_on) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ip_rsvpd != NULL) {
|
||||
rip_input(m, off);
|
||||
return;
|
||||
}
|
||||
/* Drop the packet */
|
||||
m_freem(m);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -215,9 +215,6 @@ struct rtdetq {
|
||||
struct mbuf *m; /* A copy of the packet */
|
||||
struct ifnet *ifp; /* Interface pkt came in on */
|
||||
vifi_t xmt_vif; /* Saved copy of imo_multicast_vif */
|
||||
#ifdef UPCALL_TIMING
|
||||
struct timeval t; /* Timestamp */
|
||||
#endif /* UPCALL_TIMING */
|
||||
struct rtdetq *next; /* Next in list of packets */
|
||||
};
|
||||
|
||||
|
@ -325,7 +325,9 @@ ip_output(m0, opt, ro, flags, imo, inp)
|
||||
ip->ip_ttl = imo->imo_multicast_ttl;
|
||||
if (imo->imo_multicast_vif != -1)
|
||||
ip->ip_src.s_addr =
|
||||
ip_mcast_src(imo->imo_multicast_vif);
|
||||
ip_mcast_src ?
|
||||
ip_mcast_src(imo->imo_multicast_vif) :
|
||||
INADDR_ANY;
|
||||
} else
|
||||
ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL;
|
||||
/*
|
||||
@ -385,14 +387,15 @@ ip_output(m0, opt, ro, flags, imo, inp)
|
||||
*/
|
||||
if (ip_mrouter && (flags & IP_FORWARDING) == 0) {
|
||||
/*
|
||||
* Check if rsvp daemon is running. If not, don't
|
||||
* If rsvp daemon is not running, do not
|
||||
* set ip_moptions. This ensures that the packet
|
||||
* is multicast and not just sent down one link
|
||||
* as prescribed by rsvpd.
|
||||
*/
|
||||
if (!rsvp_on)
|
||||
imo = NULL;
|
||||
if (ip_mforward(ip, ifp, m, imo) != 0) {
|
||||
imo = NULL;
|
||||
if (ip_mforward &&
|
||||
ip_mforward(ip, ifp, m, imo) != 0) {
|
||||
m_freem(m);
|
||||
goto done;
|
||||
}
|
||||
|
@ -191,9 +191,10 @@ void ipip_input(struct mbuf *, int);
|
||||
void rsvp_input(struct mbuf *, int);
|
||||
int ip_rsvp_init(struct socket *);
|
||||
int ip_rsvp_done(void);
|
||||
int ip_rsvp_vif_init(struct socket *, struct sockopt *);
|
||||
int ip_rsvp_vif_done(struct socket *, struct sockopt *);
|
||||
void ip_rsvp_force_done(struct socket *);
|
||||
extern int (*ip_rsvp_vif)(struct socket *, struct sockopt *);
|
||||
extern void (*ip_rsvp_force_done)(struct socket *);
|
||||
extern void (*rsvp_input_p)(struct mbuf *m, int off);
|
||||
|
||||
|
||||
#ifdef IPDIVERT
|
||||
void div_init(void);
|
||||
|
@ -85,6 +85,28 @@ struct inpcbinfo ripcbinfo;
|
||||
ip_fw_ctl_t *ip_fw_ctl_ptr;
|
||||
ip_dn_ctl_t *ip_dn_ctl_ptr;
|
||||
|
||||
/*
|
||||
* hooks for multicast routing. They all default to NULL,
|
||||
* so leave them not initialized and rely on BSS being set to 0.
|
||||
*/
|
||||
|
||||
/* The socket used to communicate with the multicast routing daemon. */
|
||||
struct socket *ip_mrouter;
|
||||
|
||||
/* The various mrouter and rsvp functions */
|
||||
int (*ip_mrouter_set)(struct socket *, struct sockopt *);
|
||||
int (*ip_mrouter_get)(struct socket *, struct sockopt *);
|
||||
int (*ip_mrouter_done)(void);
|
||||
int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
|
||||
struct ip_moptions *);
|
||||
int (*mrt_ioctl)(int, caddr_t);
|
||||
int (*legal_vif_num)(int);
|
||||
u_long (*ip_mcast_src)(int);
|
||||
|
||||
void (*rsvp_input_p)(struct mbuf *m, int off);
|
||||
int (*ip_rsvp_vif)(struct socket *, struct sockopt *);
|
||||
void (*ip_rsvp_force_done)(struct socket *);
|
||||
|
||||
/*
|
||||
* Nominal space allocated to a raw ip socket.
|
||||
*/
|
||||
@ -351,7 +373,8 @@ rip_ctloutput(so, sopt)
|
||||
case MRT_DEL_MFC:
|
||||
case MRT_VERSION:
|
||||
case MRT_ASSERT:
|
||||
error = ip_mrouter_get(so, sopt);
|
||||
error = ip_mrouter_get ? ip_mrouter_get(so, sopt) :
|
||||
EOPNOTSUPP;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -401,13 +424,10 @@ rip_ctloutput(so, sopt)
|
||||
error = ip_rsvp_done();
|
||||
break;
|
||||
|
||||
/* XXX - should be combined */
|
||||
case IP_RSVP_VIF_ON:
|
||||
error = ip_rsvp_vif_init(so, sopt);
|
||||
break;
|
||||
|
||||
case IP_RSVP_VIF_OFF:
|
||||
error = ip_rsvp_vif_done(so, sopt);
|
||||
error = ip_rsvp_vif ?
|
||||
ip_rsvp_vif(so, sopt) : EINVAL;
|
||||
break;
|
||||
|
||||
case MRT_INIT:
|
||||
@ -418,7 +438,8 @@ rip_ctloutput(so, sopt)
|
||||
case MRT_DEL_MFC:
|
||||
case MRT_VERSION:
|
||||
case MRT_ASSERT:
|
||||
error = ip_mrouter_set(so, sopt);
|
||||
error = ip_mrouter_set ? ip_mrouter_set(so, sopt) :
|
||||
EOPNOTSUPP;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -546,9 +567,10 @@ rip_detach(struct socket *so)
|
||||
inp = sotoinpcb(so);
|
||||
if (inp == 0)
|
||||
panic("rip_detach");
|
||||
if (so == ip_mrouter)
|
||||
if (so == ip_mrouter && ip_mrouter_done)
|
||||
ip_mrouter_done();
|
||||
ip_rsvp_force_done(so);
|
||||
if (ip_rsvp_force_done)
|
||||
ip_rsvp_force_done(so);
|
||||
if (so == ip_rsvpd)
|
||||
ip_rsvp_done();
|
||||
in_pcbdetach(inp);
|
||||
|
Loading…
Reference in New Issue
Block a user