diff --git a/package/network/services/igmpproxy/Makefile b/package/network/services/igmpproxy/Makefile index e335b72d6a..b98f3e5947 100644 --- a/package/network/services/igmpproxy/Makefile +++ b/package/network/services/igmpproxy/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=igmpproxy -PKG_VERSION:=0.1 -PKG_RELEASE:=11 +PKG_VERSION:=0.2.1 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=@SF/igmpproxy -PKG_HASH:=ee18ff3d8c3ae3a29dccb7e5eedf332337330020168bd95a11cece8d7d7ee6ae +PKG_SOURCE_URL:=https://github.com/pali/igmpproxy/releases/download/${PKG_VERSION}/ +PKG_HASH:=d351e623037390f575c1203d9cbb7ba33a8bdef85a3c5e1d2901c5a2a38449a1 PKG_MAINTAINER:=Felix Fietkau include $(INCLUDE_DIR)/package.mk diff --git a/package/network/services/igmpproxy/patches/001-Send-IGMP-packets-with-IP-Router-Alert-option-RFC-21.patch b/package/network/services/igmpproxy/patches/001-Send-IGMP-packets-with-IP-Router-Alert-option-RFC-21.patch deleted file mode 100644 index ffe1cf15eb..0000000000 --- a/package/network/services/igmpproxy/patches/001-Send-IGMP-packets-with-IP-Router-Alert-option-RFC-21.patch +++ /dev/null @@ -1,79 +0,0 @@ -From fed8c3db10bc9d3a1e799a774924c00522595d0c Mon Sep 17 00:00:00 2001 -From: Evgeny Yurchenko -Date: Mon, 4 Jan 2010 05:13:59 +0500 -Subject: [PATCH] Send IGMP packets with IP Router Alert option [RFC 2113] included in IP header - ---- - src/igmp.c | 17 ++++++++++++----- - src/igmpproxy.h | 1 + - 2 files changed, 13 insertions(+), 5 deletions(-) - -diff --git a/src/igmp.c b/src/igmp.c -index a0cd27d..b547688 100644 ---- a/src/igmp.c -+++ b/src/igmp.c -@@ -67,7 +67,7 @@ void initIgmp() { - * - Checksum (let the kernel fill it in) - */ - ip->ip_v = IPVERSION; -- ip->ip_hl = sizeof(struct ip) >> 2; -+ ip->ip_hl = (sizeof(struct ip) + 4) >> 2; /* +4 for Router Alert option */ - ip->ip_tos = 0xc0; /* Internet Control */ - ip->ip_ttl = MAXTTL; /* applies to unicasts only */ - ip->ip_p = IPPROTO_IGMP; -@@ -213,7 +213,7 @@ void buildIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, i - ip = (struct ip *)send_buf; - ip->ip_src.s_addr = src; - ip->ip_dst.s_addr = dst; -- ip_set_len(ip, MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen); -+ ip_set_len(ip, IP_HEADER_RAOPT_LEN + IGMP_MINLEN + datalen); - - if (IN_MULTICAST(ntohl(dst))) { - ip->ip_ttl = curttl; -@@ -221,13 +221,20 @@ void buildIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, i - ip->ip_ttl = MAXTTL; - } - -- igmp = (struct igmp *)(send_buf + MIN_IP_HEADER_LEN); -+ /* Add Router Alert option */ -+ ((u_char*)send_buf+MIN_IP_HEADER_LEN)[0] = IPOPT_RA; -+ ((u_char*)send_buf+MIN_IP_HEADER_LEN)[1] = 0x04; -+ ((u_char*)send_buf+MIN_IP_HEADER_LEN)[2] = 0x00; -+ ((u_char*)send_buf+MIN_IP_HEADER_LEN)[3] = 0x00; -+ -+ igmp = (struct igmp *)(send_buf + IP_HEADER_RAOPT_LEN); - igmp->igmp_type = type; - igmp->igmp_code = code; - igmp->igmp_group.s_addr = group; - igmp->igmp_cksum = 0; - igmp->igmp_cksum = inetChksum((u_short *)igmp, -- IGMP_MINLEN + datalen); -+ IP_HEADER_RAOPT_LEN + datalen); -+ - } - - /* -@@ -257,7 +264,7 @@ void sendIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, in - #endif - sdst.sin_addr.s_addr = dst; - if (sendto(MRouterFD, send_buf, -- MIN_IP_HEADER_LEN + IGMP_MINLEN + datalen, 0, -+ IP_HEADER_RAOPT_LEN + IGMP_MINLEN + datalen, 0, - (struct sockaddr *)&sdst, sizeof(sdst)) < 0) { - if (errno == ENETDOWN) - my_log(LOG_ERR, errno, "Sender VIF was down."); -diff --git a/src/igmpproxy.h b/src/igmpproxy.h -index 0de7791..4df8a79 100644 ---- a/src/igmpproxy.h -+++ b/src/igmpproxy.h -@@ -64,6 +64,7 @@ - #define MAX_IP_PACKET_LEN 576 - #define MIN_IP_HEADER_LEN 20 - #define MAX_IP_HEADER_LEN 60 -+#define IP_HEADER_RAOPT_LEN 24 - - #define MAX_MC_VIFS 32 // !!! check this const in the specific includes - --- -1.7.2.5 - diff --git a/package/network/services/igmpproxy/patches/002-Change-default-interface-state-to-disabled-wrt-29458.patch b/package/network/services/igmpproxy/patches/002-Change-default-interface-state-to-disabled-wrt-29458.patch deleted file mode 100644 index d7550d7961..0000000000 --- a/package/network/services/igmpproxy/patches/002-Change-default-interface-state-to-disabled-wrt-29458.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 85e240727305b156097ee7aa0f0c4473a136291f Mon Sep 17 00:00:00 2001 -From: Constantin Baranov -Date: Tue, 23 Feb 2010 21:08:02 +0400 -Subject: [PATCH] Change default interface state to disabled (wrt #2945877) - ---- - src/ifvc.c | 2 +- - src/igmpproxy.c | 6 ++++-- - 2 files changed, 5 insertions(+), 3 deletions(-) - -diff --git a/src/ifvc.c b/src/ifvc.c -index 545b3b4..9d7ee97 100644 ---- a/src/ifvc.c -+++ b/src/ifvc.c -@@ -139,7 +139,7 @@ void buildIfVc() { - IfDescEp->allowednets->subnet_addr = subnet; - - // Set the default params for the IF... -- IfDescEp->state = IF_STATE_DOWNSTREAM; -+ IfDescEp->state = IF_STATE_DISABLED; - IfDescEp->robustness = DEFAULT_ROBUSTNESS; - IfDescEp->threshold = DEFAULT_THRESHOLD; /* ttl limit */ - IfDescEp->ratelimit = DEFAULT_RATELIMIT; -diff --git a/src/igmpproxy.c b/src/igmpproxy.c -index 1ece15a..35000c7 100644 ---- a/src/igmpproxy.c -+++ b/src/igmpproxy.c -@@ -186,8 +186,10 @@ int igmpProxyInit() { - } - } - -- addVIF( Dp ); -- vifcount++; -+ if (Dp->state != IF_STATE_DISABLED) { -+ addVIF( Dp ); -+ vifcount++; -+ } - } - } - --- -1.7.2.5 - diff --git a/package/network/services/igmpproxy/patches/003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch b/package/network/services/igmpproxy/patches/003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch deleted file mode 100644 index 90d4d5f25f..0000000000 --- a/package/network/services/igmpproxy/patches/003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 65f777e7f66b55239d935c1cf81bb5abc0f6c89f Mon Sep 17 00:00:00 2001 -From: Grinch -Date: Sun, 16 Aug 2009 19:58:26 +0500 -Subject: [PATCH] Restrict igmp reports for downstream interfaces (wrt #2833339) - -atm all igmp membership reports are forwarded to the upstream interface. -Unfortunately some ISP Providers restrict some multicast groups (esp. those -that are defined as local link groups and that are not supposed to be -forwarded to the wan, i.e 224.0.0.0/24). Therefore there should be some -kind of black oder whitelisting. -As whitelisting can be accomplished quite easy I wrote a litte patch, which -is attached to this request. ---- - doc/igmpproxy.conf.5.in | 19 +++++++++++++++++++ - src/config.c | 23 ++++++++++++++++++++++- - src/igmpproxy.h | 1 + - src/request.c | 20 ++++++++++++++++---- - 4 files changed, 58 insertions(+), 5 deletions(-) - -diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in -index a4ea7d0..56efa22 100644 ---- a/doc/igmpproxy.conf.5.in -+++ b/doc/igmpproxy.conf.5.in -@@ -116,6 +116,25 @@ This is especially useful for the upstream interface, since the source for multi - traffic is often from a remote location. Any number of altnet parameters can be specified. - .RE - -+.B whitelist -+.I networkaddr -+.RS -+Defines a whitelist for multicast groups. The network address must be in the following -+format 'a.b.c.d/n'. If you want to allow one single group use a network mask of /32, -+i.e. 'a.b.c.d/32'. -+ -+By default all multicast groups are allowed on any downstream interface. If at least one -+whitelist entry is defined, all igmp membership reports for not explicitly whitelisted -+multicast groups will be ignored and therefore not be served by igmpproxy. This is especially -+useful, if your provider does only allow a predefined set of multicast groups. These whitelists -+are only obeyed by igmpproxy itself, they won't prevent any other igmp client running on the -+same machine as igmpproxy from requesting 'unallowed' multicast groups. -+ -+You may specify as many whitelist entries as needed. Although you should keep it as simple as -+possible, as this list is parsed for every membership report and therefore this increases igmp -+response times. Often used or large groups should be defined first, as parsing ends as soon as -+a group matches an entry. -+.RE - - .SH EXAMPLE - ## Enable quickleave -diff --git a/src/config.c b/src/config.c -index 5a96ce0..d72619f 100644 ---- a/src/config.c -+++ b/src/config.c -@@ -46,6 +46,9 @@ struct vifconfig { - - // Keep allowed nets for VIF. - struct SubnetList* allowednets; -+ -+ // Allowed Groups -+ struct SubnetList* allowedgroups; - - // Next config in list... - struct vifconfig* next; -@@ -202,6 +205,8 @@ void configureVifs() { - // Insert the configured nets... - vifLast->next = confPtr->allowednets; - -+ Dp->allowedgroups = confPtr->allowedgroups; -+ - break; - } - } -@@ -215,7 +220,7 @@ void configureVifs() { - */ - struct vifconfig *parsePhyintToken() { - struct vifconfig *tmpPtr; -- struct SubnetList **anetPtr; -+ struct SubnetList **anetPtr, **agrpPtr; - char *token; - short parseError = 0; - -@@ -239,6 +244,7 @@ struct vifconfig *parsePhyintToken() { - tmpPtr->threshold = 1; - tmpPtr->state = IF_STATE_DOWNSTREAM; - tmpPtr->allowednets = NULL; -+ tmpPtr->allowedgroups = NULL; - - // Make a copy of the token to store the IF name - tmpPtr->name = strdup( token ); -@@ -248,6 +254,7 @@ struct vifconfig *parsePhyintToken() { - - // Set the altnet pointer to the allowednets pointer. - anetPtr = &tmpPtr->allowednets; -+ agrpPtr = &tmpPtr->allowedgroups; - - // Parse the rest of the config.. - token = nextConfigToken(); -@@ -266,6 +273,20 @@ struct vifconfig *parsePhyintToken() { - anetPtr = &(*anetPtr)->next; - } - } -+ else if(strcmp("whitelist", token)==0) { -+ // Whitelist -+ token = nextConfigToken(); -+ my_log(LOG_DEBUG, 0, "Config: IF: Got whitelist token %s.", token); -+ -+ *agrpPtr = parseSubnetAddress(token); -+ if(*agrpPtr == NULL) { -+ parseError = 1; -+ my_log(LOG_WARNING, 0, "Unable to parse subnet address."); -+ break; -+ } else { -+ agrpPtr = &(*agrpPtr)->next; -+ } -+ } - else if(strcmp("upstream", token)==0) { - // Upstream - my_log(LOG_DEBUG, 0, "Config: IF: Got upstream token."); -diff --git a/src/igmpproxy.h b/src/igmpproxy.h -index 4dabd1c..0de7791 100644 ---- a/src/igmpproxy.h -+++ b/src/igmpproxy.h -@@ -145,6 +145,7 @@ struct IfDesc { - short Flags; - short state; - struct SubnetList* allowednets; -+ struct SubnetList* allowedgroups; - unsigned int robustness; - unsigned char threshold; /* ttl limit */ - unsigned int ratelimit; -diff --git a/src/request.c b/src/request.c -index e3589f6..89b91de 100644 ---- a/src/request.c -+++ b/src/request.c -@@ -82,10 +82,22 @@ void acceptGroupReport(uint32_t src, uint32_t group, uint8_t type) { - my_log(LOG_DEBUG, 0, "Should insert group %s (from: %s) to route table. Vif Ix : %d", - inetFmt(group,s1), inetFmt(src,s2), sourceVif->index); - -- // The membership report was OK... Insert it into the route table.. -- insertRoute(group, sourceVif->index); -- -- -+ // If we don't have a whitelist we insertRoute and done -+ if(sourceVif->allowedgroups == NULL) -+ { -+ insertRoute(group, sourceVif->index); -+ return; -+ } -+ // Check if this Request is legit on this interface -+ struct SubnetList *sn; -+ for(sn = sourceVif->allowedgroups; sn != NULL; sn = sn->next) -+ if((group & sn->subnet_mask) == sn->subnet_addr) -+ { -+ // The membership report was OK... Insert it into the route table.. -+ insertRoute(group, sourceVif->index); -+ return; -+ } -+ my_log(LOG_INFO, 0, "The group address %s may not be requested from this interface. Ignoring.", inetFmt(group, s1)); - } else { - // Log the state of the interface the report was recieved on. - my_log(LOG_INFO, 0, "Mebership report was recieved on %s. Ignoring.", --- -1.7.2.5 - diff --git a/package/network/services/igmpproxy/patches/004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch b/package/network/services/igmpproxy/patches/004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch deleted file mode 100644 index a4caed72d2..0000000000 --- a/package/network/services/igmpproxy/patches/004-Restrict-igmp-reports-forwarding-to-upstream-interfa.patch +++ /dev/null @@ -1,62 +0,0 @@ -From bcd7c648e86d97263c931de53a008c9629e7797e Mon Sep 17 00:00:00 2001 -From: Stefan Becker -Date: Fri, 11 Dec 2009 21:08:57 +0200 -Subject: [PATCH] Restrict igmp reports forwarding to upstream interface - -Utilize the new "whitelist" keyword also on the upstream interface definition. -If specified then only whitelisted multicast groups will be forwarded upstream. - -This can be used to avoid publishing private multicast groups to the world, -e.g. SSDP from a UPnP server on the internal network. ---- - doc/igmpproxy.conf.5.in | 5 +++++ - src/rttable.c | 17 +++++++++++++++++ - 2 files changed, 22 insertions(+), 0 deletions(-) - -diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in -index 56efa22..d916f05 100644 ---- a/doc/igmpproxy.conf.5.in -+++ b/doc/igmpproxy.conf.5.in -@@ -134,6 +134,11 @@ You may specify as many whitelist entries as needed. Although you should keep it - possible, as this list is parsed for every membership report and therefore this increases igmp - response times. Often used or large groups should be defined first, as parsing ends as soon as - a group matches an entry. -+ -+You may also specify whitelist entries for the upstream interface. Only igmp membership reports -+for explicitely whitelisted multicast groups will be sent out on the upstream interface. This -+is useful if you want to use multicast groups only between your downstream interfaces, like SSDP -+from a UPnP server. - .RE - - .SH EXAMPLE -diff --git a/src/rttable.c b/src/rttable.c -index f0701a8..77dd791 100644 ---- a/src/rttable.c -+++ b/src/rttable.c -@@ -117,6 +117,23 @@ void sendJoinLeaveUpstream(struct RouteTable* route, int join) { - my_log(LOG_ERR, 0 ,"FATAL: Unable to get Upstream IF."); - } - -+ // Check if there is a white list for the upstram VIF -+ if (upstrIf->allowedgroups != NULL) { -+ uint32_t group = route->group; -+ struct SubnetList* sn; -+ -+ // Check if this Request is legit to be forwarded to upstream -+ for(sn = upstrIf->allowedgroups; sn != NULL; sn = sn->next) -+ if((group & sn->subnet_mask) == sn->subnet_addr) -+ // Forward is OK... -+ break; -+ -+ if (sn == NULL) { -+ my_log(LOG_INFO, 0, "The group address %s may not be forwarded upstream. Ignoring.", inetFmt(group, s1)); -+ return; -+ } -+ } -+ - // Send join or leave request... - if(join) { - --- -1.7.2.5 - diff --git a/package/network/services/igmpproxy/patches/010-missing_include.patch b/package/network/services/igmpproxy/patches/010-missing_include.patch deleted file mode 100644 index af0eab845b..0000000000 --- a/package/network/services/igmpproxy/patches/010-missing_include.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/src/os-linux.h -+++ b/src/os-linux.h -@@ -3,6 +3,7 @@ - #include - #include - #include -+#include - - static inline u_short ip_data_len(const struct ip *ip) - { diff --git a/package/network/services/igmpproxy/patches/020-Silence-downstream-interface-igmp-messages.patch b/package/network/services/igmpproxy/patches/020-Silence-downstream-interface-igmp-messages.patch deleted file mode 100644 index ccd000c638..0000000000 --- a/package/network/services/igmpproxy/patches/020-Silence-downstream-interface-igmp-messages.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/src/igmp.c -+++ b/src/igmp.c -@@ -139,8 +139,14 @@ - return; - } - else if(!isAdressValidForIf(checkVIF, src)) { -- my_log(LOG_WARNING, 0, "The source address %s for group %s, is not in any valid net for upstream VIF.", -- inetFmt(src, s1), inetFmt(dst, s2)); -+ struct IfDesc *downVIF = getIfByAddress(src); -+ if (downVIF && downVIF->state & IF_STATE_DOWNSTREAM) { -+ my_log(LOG_NOTICE, 0, "The source address %s for group %s is from downstream VIF. Ignoring.", -+ inetFmt(src, s1), inetFmt(dst, s2)); -+ } else { -+ my_log(LOG_WARNING, 0, "The source address %s for group %s, is not in any valid net for upstream VIF.", -+ inetFmt(src, s1), inetFmt(dst, s2)); -+ } - return; - } - diff --git a/package/network/services/igmpproxy/patches/100-use-monotic-clock-instead-of-time-of-day.patch b/package/network/services/igmpproxy/patches/100-use-monotic-clock-instead-of-time-of-day.patch deleted file mode 100644 index e75283c036..0000000000 --- a/package/network/services/igmpproxy/patches/100-use-monotic-clock-instead-of-time-of-day.patch +++ /dev/null @@ -1,120 +0,0 @@ -From d0e66e0719ae8eb549f7cc220fdc66575d3db332 Mon Sep 17 00:00:00 2001 -From: Jonas Gorski -Date: Thu, 29 Mar 2012 17:01:11 +0200 -Subject: [PATCH 4/4] use monotic clock instead of time of day - -The time of day might chance e.g. by daylight savings time during the -runtime, which causes timers to fire repeatedly for a long time. - -Contributed by T-Labs, Deutsche Telekom Innovation Laboratories - -Signed-off-by: Jonas Gorski ---- - configure.ac | 2 ++ - src/igmpproxy.c | 26 +++++++++++++------------- - src/igmpproxy.h | 3 ++- - 3 files changed, 17 insertions(+), 14 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 85beb08..bd84eba 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -25,6 +25,8 @@ AC_CHECK_MEMBERS([struct sockaddr_in.sin_len], [], [], [[ - #include - ]]) - -+AC_SEARCH_LIBS([clock_gettime],[rt]) -+ - AC_CONFIG_FILES([ - Makefile - doc/Makefile -diff --git a/src/igmpproxy.c b/src/igmpproxy.c -index 35000c7..3a9ccad 100644 ---- a/src/igmpproxy.c -+++ b/src/igmpproxy.c -@@ -234,13 +234,13 @@ void igmpProxyRun() { - int MaxFD, Rt, secs; - fd_set ReadFDS; - socklen_t dummy = 0; -- struct timeval curtime, lasttime, difftime, tv; -+ struct timespec curtime, lasttime, difftime, tv; - // The timeout is a pointer in order to set it to NULL if nessecary. -- struct timeval *timeout = &tv; -+ struct timespec *timeout = &tv; - - // Initialize timer vars -- difftime.tv_usec = 0; -- gettimeofday(&curtime, NULL); -+ difftime.tv_nsec = 0; -+ clock_gettime(CLOCK_MONOTONIC, &curtime); - lasttime = curtime; - - // First thing we send a membership query in downstream VIF's... -@@ -263,7 +263,7 @@ void igmpProxyRun() { - if(secs == -1) { - timeout = NULL; - } else { -- timeout->tv_usec = 0; -+ timeout->tv_nsec = 0; - timeout->tv_sec = secs; - } - -@@ -274,7 +274,7 @@ void igmpProxyRun() { - FD_SET( MRouterFD, &ReadFDS ); - - // wait for input -- Rt = select( MaxFD +1, &ReadFDS, NULL, NULL, timeout ); -+ Rt = pselect( MaxFD +1, &ReadFDS, NULL, NULL, timeout, NULL ); - - // log and ignore failures - if( Rt < 0 ) { -@@ -307,20 +307,20 @@ void igmpProxyRun() { - */ - if (Rt == 0) { - curtime.tv_sec = lasttime.tv_sec + secs; -- curtime.tv_usec = lasttime.tv_usec; -+ curtime.tv_nsec = lasttime.tv_nsec; - Rt = -1; /* don't do this next time through the loop */ - } else { -- gettimeofday(&curtime, NULL); -+ clock_gettime(CLOCK_MONOTONIC, &curtime); - } - difftime.tv_sec = curtime.tv_sec - lasttime.tv_sec; -- difftime.tv_usec += curtime.tv_usec - lasttime.tv_usec; -- while (difftime.tv_usec > 1000000) { -+ difftime.tv_nsec += curtime.tv_nsec - lasttime.tv_nsec; -+ while (difftime.tv_nsec > 1000000000) { - difftime.tv_sec++; -- difftime.tv_usec -= 1000000; -+ difftime.tv_nsec -= 1000000000; - } -- if (difftime.tv_usec < 0) { -+ if (difftime.tv_nsec < 0) { - difftime.tv_sec--; -- difftime.tv_usec += 1000000; -+ difftime.tv_nsec += 1000000000; - } - lasttime = curtime; - if (secs == 0 || difftime.tv_sec > 0) -diff --git a/src/igmpproxy.h b/src/igmpproxy.h -index 4df8a79..36a4f04 100644 ---- a/src/igmpproxy.h -+++ b/src/igmpproxy.h -@@ -44,12 +44,13 @@ - #include - #include - #include -+#include - - #include - #include --#include - #include - #include -+#include - - #include - #include --- -1.7.2.5 - diff --git a/package/network/services/igmpproxy/patches/200-allow_wildcard_addr.patch b/package/network/services/igmpproxy/patches/200-allow_wildcard_addr.patch deleted file mode 100644 index 0dd772007a..0000000000 --- a/package/network/services/igmpproxy/patches/200-allow_wildcard_addr.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/src/config.c -+++ b/src/config.c -@@ -357,15 +357,18 @@ struct SubnetList *parseSubnetAddress(ch - tmpStr = strtok(NULL, "/"); - if(tmpStr != NULL) { - int bitcnt = atoi(tmpStr); -- if(bitcnt <= 0 || bitcnt > 32) { -+ if(bitcnt < 0 || bitcnt > 32) { - my_log(LOG_WARNING, 0, "The bits part of the address is invalid : %d.",tmpStr); - return NULL; - } - -- mask <<= (32 - bitcnt); -+ if (bitcnt == 0) -+ mask = 0; -+ else -+ mask <<= (32 - bitcnt); - } - -- if(addr == -1 || addr == 0) { -+ if(addr == -1) { - my_log(LOG_WARNING, 0, "Unable to parse address token '%s'.", addrstr); - return NULL; - } diff --git a/package/network/services/igmpproxy/patches/250-fix_multiple_downlink_interfaces.patch b/package/network/services/igmpproxy/patches/250-fix_multiple_downlink_interfaces.patch deleted file mode 100644 index 24aefcef26..0000000000 --- a/package/network/services/igmpproxy/patches/250-fix_multiple_downlink_interfaces.patch +++ /dev/null @@ -1,154 +0,0 @@ ---- a/src/igmpproxy.h -+++ b/src/igmpproxy.h -@@ -251,6 +251,7 @@ int activateRoute(uint32_t group, uint32 - void ageActiveRoutes(); - void setRouteLastMemberMode(uint32_t group); - int lastMemberGroupAge(uint32_t group); -+int interfaceInRoute(int32_t group, int Ix); - - /* request.c - */ ---- a/src/request.c -+++ b/src/request.c -@@ -41,10 +41,10 @@ - - // Prototypes... - void sendGroupSpecificMemberQuery(void *argument); -- -+ - typedef struct { - uint32_t group; -- uint32_t vifAddr; -+ // uint32_t vifAddr; - short started; - } GroupVifDesc; - -@@ -142,7 +142,7 @@ void acceptLeaveMessage(uint32_t src, ui - - // Call the group spesific membership querier... - gvDesc->group = group; -- gvDesc->vifAddr = sourceVif->InAdr.s_addr; -+ // gvDesc->vifAddr = sourceVif->InAdr.s_addr; - gvDesc->started = 0; - - sendGroupSpecificMemberQuery(gvDesc); -@@ -159,6 +159,9 @@ void acceptLeaveMessage(uint32_t src, ui - */ - void sendGroupSpecificMemberQuery(void *argument) { - struct Config *conf = getCommonConfig(); -+ struct IfDesc *Dp; -+ struct RouteTable *croute; -+ int Ix; - - // Cast argument to correct type... - GroupVifDesc *gvDesc = (GroupVifDesc*) argument; -@@ -166,22 +169,38 @@ void sendGroupSpecificMemberQuery(void * - if(gvDesc->started) { - // If aging returns false, we don't do any further action... - if(!lastMemberGroupAge(gvDesc->group)) { -+ // FIXME: Should we free gvDesc here? - return; - } - } else { - gvDesc->started = 1; - } - -- // Send a group specific membership query... -- sendIgmp(gvDesc->vifAddr, gvDesc->group, -- IGMP_MEMBERSHIP_QUERY, -- conf->lastMemberQueryInterval * IGMP_TIMER_SCALE, -- gvDesc->group, 0); -- -- my_log(LOG_DEBUG, 0, "Sent membership query from %s to %s. Delay: %d", -- inetFmt(gvDesc->vifAddr,s1), inetFmt(gvDesc->group,s2), -- conf->lastMemberQueryInterval); -- -+ /** -+ * FIXME: This loops through all interfaces the group is active on an sends queries. -+ * It might be better to send only a query on the interface the leave was accepted on and remove only that interface from the route. -+ */ -+ -+ // Loop through all downstream interfaces -+ for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) { -+ if ( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) ) { -+ if(Dp->state == IF_STATE_DOWNSTREAM) { -+ // Is that interface used in the group? -+ if (interfaceInRoute(gvDesc->group ,Dp->index)) { -+ -+ // Send a group specific membership query... -+ sendIgmp(Dp->InAdr.s_addr, gvDesc->group, -+ IGMP_MEMBERSHIP_QUERY, -+ conf->lastMemberQueryInterval * IGMP_TIMER_SCALE, -+ gvDesc->group, 0); -+ -+ my_log(LOG_DEBUG, 0, "Sent membership query from %s to %s. Delay: %d", -+ inetFmt(Dp->InAdr.s_addr,s1), inetFmt(gvDesc->group,s2), -+ conf->lastMemberQueryInterval); -+ } -+ } -+ } -+ } - // Set timeout for next round... - timer_setTimer(conf->lastMemberQueryInterval, sendGroupSpecificMemberQuery, gvDesc); - ---- a/src/rttable.c -+++ b/src/rttable.c -@@ -428,6 +428,25 @@ void ageActiveRoutes() { - } - - /** -+* Counts the number of interfaces a given route is active on -+*/ -+int numberOfInterfaces(struct RouteTable *croute) { -+ int Ix; -+ struct IfDesc *Dp; -+ int result = 0; -+ // Loop through all interfaces -+ for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) { -+ // If the interface is used by the route, increase counter -+ if(BIT_TST(croute->vifBits, Dp->index)) { -+ result++; -+ } -+ } -+ my_log(LOG_DEBUG, 0, "counted %d interfaces", result); -+ return result; -+} -+ -+ -+/** - * Should be called when a leave message is recieved, to - * mark a route for the last member probe state. - */ -@@ -439,8 +458,11 @@ void setRouteLastMemberMode(uint32_t gro - if(croute!=NULL) { - // Check for fast leave mode... - if(croute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave) { -- // Send a leave message right away.. -- sendJoinLeaveUpstream(croute, 0); -+ // Send a leave message right away only when the route has been active on only one interface -+ if (numberOfInterfaces(croute) <= 1) { -+ my_log(LOG_DEBUG, 0, "Leaving group %d now", group); -+ sendJoinLeaveUpstream(croute, 0); -+ } - } - // Set the routingstate to Last member check... - croute->upstrState = ROUTESTATE_CHECK_LAST_MEMBER; -@@ -677,3 +699,18 @@ void logRouteTable(char *header) { - - my_log(LOG_DEBUG, 0, "-----------------------------------------------------"); - } -+ -+/** -+* Returns true when the given group belongs to the given interface -+*/ -+int interfaceInRoute(int32_t group, int Ix) { -+ struct RouteTable* croute; -+ croute = findRoute(group); -+ if (croute != NULL) { -+ my_log(LOG_DEBUG, 0, "Interface id %d is in group $d", Ix, group); -+ return BIT_TST(croute->vifBits, Ix); -+ } else { -+ return 0; -+ } -+} -+