003-Restrict-igmp-reports-for-downstream-interfaces-wrt-.patch 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. From 65f777e7f66b55239d935c1cf81bb5abc0f6c89f Mon Sep 17 00:00:00 2001
  2. From: Grinch <grinch79@users.sourceforge.net>
  3. Date: Sun, 16 Aug 2009 19:58:26 +0500
  4. Subject: [PATCH] Restrict igmp reports for downstream interfaces (wrt #2833339)
  5. atm all igmp membership reports are forwarded to the upstream interface.
  6. Unfortunately some ISP Providers restrict some multicast groups (esp. those
  7. that are defined as local link groups and that are not supposed to be
  8. forwarded to the wan, i.e 224.0.0.0/24). Therefore there should be some
  9. kind of black oder whitelisting.
  10. As whitelisting can be accomplished quite easy I wrote a litte patch, which
  11. is attached to this request.
  12. ---
  13. doc/igmpproxy.conf.5.in | 19 +++++++++++++++++++
  14. src/config.c | 23 ++++++++++++++++++++++-
  15. src/igmpproxy.h | 1 +
  16. src/request.c | 20 ++++++++++++++++----
  17. 4 files changed, 58 insertions(+), 5 deletions(-)
  18. diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in
  19. index a4ea7d0..56efa22 100644
  20. --- a/doc/igmpproxy.conf.5.in
  21. +++ b/doc/igmpproxy.conf.5.in
  22. @@ -116,6 +116,25 @@ This is especially useful for the upstream interface, since the source for multi
  23. traffic is often from a remote location. Any number of altnet parameters can be specified.
  24. .RE
  25. +.B whitelist
  26. +.I networkaddr
  27. +.RS
  28. +Defines a whitelist for multicast groups. The network address must be in the following
  29. +format 'a.b.c.d/n'. If you want to allow one single group use a network mask of /32,
  30. +i.e. 'a.b.c.d/32'.
  31. +
  32. +By default all multicast groups are allowed on any downstream interface. If at least one
  33. +whitelist entry is defined, all igmp membership reports for not explicitly whitelisted
  34. +multicast groups will be ignored and therefore not be served by igmpproxy. This is especially
  35. +useful, if your provider does only allow a predefined set of multicast groups. These whitelists
  36. +are only obeyed by igmpproxy itself, they won't prevent any other igmp client running on the
  37. +same machine as igmpproxy from requesting 'unallowed' multicast groups.
  38. +
  39. +You may specify as many whitelist entries as needed. Although you should keep it as simple as
  40. +possible, as this list is parsed for every membership report and therefore this increases igmp
  41. +response times. Often used or large groups should be defined first, as parsing ends as soon as
  42. +a group matches an entry.
  43. +.RE
  44. .SH EXAMPLE
  45. ## Enable quickleave
  46. diff --git a/src/config.c b/src/config.c
  47. index 5a96ce0..d72619f 100644
  48. --- a/src/config.c
  49. +++ b/src/config.c
  50. @@ -46,6 +46,9 @@ struct vifconfig {
  51. // Keep allowed nets for VIF.
  52. struct SubnetList* allowednets;
  53. +
  54. + // Allowed Groups
  55. + struct SubnetList* allowedgroups;
  56. // Next config in list...
  57. struct vifconfig* next;
  58. @@ -202,6 +205,8 @@ void configureVifs() {
  59. // Insert the configured nets...
  60. vifLast->next = confPtr->allowednets;
  61. + Dp->allowedgroups = confPtr->allowedgroups;
  62. +
  63. break;
  64. }
  65. }
  66. @@ -215,7 +220,7 @@ void configureVifs() {
  67. */
  68. struct vifconfig *parsePhyintToken() {
  69. struct vifconfig *tmpPtr;
  70. - struct SubnetList **anetPtr;
  71. + struct SubnetList **anetPtr, **agrpPtr;
  72. char *token;
  73. short parseError = 0;
  74. @@ -239,6 +244,7 @@ struct vifconfig *parsePhyintToken() {
  75. tmpPtr->threshold = 1;
  76. tmpPtr->state = IF_STATE_DOWNSTREAM;
  77. tmpPtr->allowednets = NULL;
  78. + tmpPtr->allowedgroups = NULL;
  79. // Make a copy of the token to store the IF name
  80. tmpPtr->name = strdup( token );
  81. @@ -248,6 +254,7 @@ struct vifconfig *parsePhyintToken() {
  82. // Set the altnet pointer to the allowednets pointer.
  83. anetPtr = &tmpPtr->allowednets;
  84. + agrpPtr = &tmpPtr->allowedgroups;
  85. // Parse the rest of the config..
  86. token = nextConfigToken();
  87. @@ -266,6 +273,20 @@ struct vifconfig *parsePhyintToken() {
  88. anetPtr = &(*anetPtr)->next;
  89. }
  90. }
  91. + else if(strcmp("whitelist", token)==0) {
  92. + // Whitelist
  93. + token = nextConfigToken();
  94. + my_log(LOG_DEBUG, 0, "Config: IF: Got whitelist token %s.", token);
  95. +
  96. + *agrpPtr = parseSubnetAddress(token);
  97. + if(*agrpPtr == NULL) {
  98. + parseError = 1;
  99. + my_log(LOG_WARNING, 0, "Unable to parse subnet address.");
  100. + break;
  101. + } else {
  102. + agrpPtr = &(*agrpPtr)->next;
  103. + }
  104. + }
  105. else if(strcmp("upstream", token)==0) {
  106. // Upstream
  107. my_log(LOG_DEBUG, 0, "Config: IF: Got upstream token.");
  108. diff --git a/src/igmpproxy.h b/src/igmpproxy.h
  109. index 4dabd1c..0de7791 100644
  110. --- a/src/igmpproxy.h
  111. +++ b/src/igmpproxy.h
  112. @@ -145,6 +145,7 @@ struct IfDesc {
  113. short Flags;
  114. short state;
  115. struct SubnetList* allowednets;
  116. + struct SubnetList* allowedgroups;
  117. unsigned int robustness;
  118. unsigned char threshold; /* ttl limit */
  119. unsigned int ratelimit;
  120. diff --git a/src/request.c b/src/request.c
  121. index e3589f6..89b91de 100644
  122. --- a/src/request.c
  123. +++ b/src/request.c
  124. @@ -82,10 +82,22 @@ void acceptGroupReport(uint32_t src, uint32_t group, uint8_t type) {
  125. my_log(LOG_DEBUG, 0, "Should insert group %s (from: %s) to route table. Vif Ix : %d",
  126. inetFmt(group,s1), inetFmt(src,s2), sourceVif->index);
  127. - // The membership report was OK... Insert it into the route table..
  128. - insertRoute(group, sourceVif->index);
  129. -
  130. -
  131. + // If we don't have a whitelist we insertRoute and done
  132. + if(sourceVif->allowedgroups == NULL)
  133. + {
  134. + insertRoute(group, sourceVif->index);
  135. + return;
  136. + }
  137. + // Check if this Request is legit on this interface
  138. + struct SubnetList *sn;
  139. + for(sn = sourceVif->allowedgroups; sn != NULL; sn = sn->next)
  140. + if((group & sn->subnet_mask) == sn->subnet_addr)
  141. + {
  142. + // The membership report was OK... Insert it into the route table..
  143. + insertRoute(group, sourceVif->index);
  144. + return;
  145. + }
  146. + my_log(LOG_INFO, 0, "The group address %s may not be requested from this interface. Ignoring.", inetFmt(group, s1));
  147. } else {
  148. // Log the state of the interface the report was recieved on.
  149. my_log(LOG_INFO, 0, "Mebership report was recieved on %s. Ignoring.",
  150. --
  151. 1.7.2.5