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:
Luigi Rizzo 2002-11-15 22:53:53 +00:00
parent 4001ea8d00
commit bbb4330b61
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=106968
8 changed files with 593 additions and 885 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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 */
};

View File

@ -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;
}

View File

@ -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);

View File

@ -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);