diff options
author | 2007-09-18 18:56:02 +0000 | |
---|---|---|
committer | 2007-09-18 18:56:02 +0000 | |
commit | a5d0ca94882b0afc2a1a9dccdaeae0bbb296e7f0 (patch) | |
tree | fe98b7415f17b642d6b0373d92c01f1ef3b1f2f4 /sys/netinet/ip_output.c | |
parent | allow state reuse for tcp if both sides are in FIN_WAIT_2 and a new SYN (diff) | |
download | wireguard-openbsd-a5d0ca94882b0afc2a1a9dccdaeae0bbb296e7f0.tar.xz wireguard-openbsd-a5d0ca94882b0afc2a1a9dccdaeae0bbb296e7f0.zip |
allow 4095 instead of 20 multicast group memberships per socket (you need
one entry for each multicast group and interface combination). this allows
you to run OSPF with more than 10 interfaces.
adapted from freebsd; ok claudio, henning, mpf
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r-- | sys/netinet/ip_output.c | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index e4c01b26373..73490dcc154 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.188 2007/07/20 19:00:35 claudio Exp $ */ +/* $OpenBSD: ip_output.c,v 1.189 2007/09/18 18:56:02 markus Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -1703,6 +1703,7 @@ ip_setmoptions(optname, imop, m) struct ip_mreq *mreq; struct ifnet *ifp; struct ip_moptions *imo = *imop; + struct in_multi **immp; struct route ro; struct sockaddr_in *dst; @@ -1712,13 +1713,17 @@ ip_setmoptions(optname, imop, m) * allocate one and initialize to default values. */ imo = (struct ip_moptions *)malloc(sizeof(*imo), M_IPMOPTS, - M_WAITOK); - + M_WAITOK|M_ZERO); + immp = (struct in_multi **)malloc( + (sizeof(*immp) * IP_MIN_MEMBERSHIPS), M_IPMOPTS, + M_WAITOK|M_ZERO); *imop = imo; imo->imo_multicast_ifp = NULL; imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL; imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP; imo->imo_num_memberships = 0; + imo->imo_max_memberships = IP_MIN_MEMBERSHIPS; + imo->imo_membership = immp; } switch (optname) { @@ -1834,9 +1839,34 @@ ip_setmoptions(optname, imop, m) error = EADDRINUSE; break; } - if (i == IP_MAX_MEMBERSHIPS) { - error = ETOOMANYREFS; - break; + if (imo->imo_num_memberships == imo->imo_max_memberships) { + struct in_multi **nmships, **omships; + size_t newmax; + /* + * Resize the vector to next power-of-two minus 1. If the + * size would exceed the maximum then we know we've really + * run out of entries. Otherwise, we reallocate the vector. + */ + nmships = NULL; + omships = imo->imo_membership; + newmax = ((imo->imo_max_memberships + 1) * 2) - 1; + if (newmax <= IP_MAX_MEMBERSHIPS) { + nmships = (struct in_multi **)malloc( + sizeof(*nmships) * newmax, M_IPMOPTS, + M_NOWAIT|M_ZERO); + if (nmships != NULL) { + bcopy(omships, nmships, + sizeof(*omships) * + imo->imo_max_memberships); + free(omships, M_IPMOPTS); + imo->imo_membership = nmships; + imo->imo_max_memberships = newmax; + } + } + if (nmships == NULL) { + error = ETOOMANYREFS; + break; + } } /* * Everything looks good; add a new record to the multicast @@ -1910,12 +1940,13 @@ ip_setmoptions(optname, imop, m) } /* - * If all options have default values, no need to keep the mbuf. + * If all options have default values, no need to keep the data. */ if (imo->imo_multicast_ifp == NULL && imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL && imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP && imo->imo_num_memberships == 0) { + free(imo->imo_membership , M_IPMOPTS); free(*imop, M_IPMOPTS); *imop = NULL; } @@ -1984,6 +2015,7 @@ ip_freemoptions(imo) if (imo != NULL) { for (i = 0; i < imo->imo_num_memberships; ++i) in_delmulti(imo->imo_membership[i]); + free(imo->imo_membership, M_IPMOPTS); free(imo, M_IPMOPTS); } } |