Skip to content

Commit

Permalink
Fix issue #26: Enhance pimd with IGMPv3 support in IGMPv2 compat mode
Browse files Browse the repository at this point in the history
This commit adds initial IGMPv3 support to pimd.  Hence, no PIM-SSM
support yet, only to be able to support IGMPv3 membership reports.

Signed-off-by: Gil Beniamini <[email protected]>
Signed-off-by: Joachim Nilsson <[email protected]>
  • Loading branch information
Gil Beniamini authored and troglobit committed Jan 3, 2014
1 parent e2ebe8e commit 83c824f
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
78 changes: 78 additions & 0 deletions igmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,42 @@

#include "defs.h"

//#ifdef GIL_SUPPORT_IGMPV3 //24Oct13, can be moved to ./igmpv3.h
#define IGMPV3_HOST_MEMBERSHIP_REPORT 0x22 /* V3 version of 0x11 */
/* V3 group record types [grec_type] */
#define IGMPV3_MODE_IS_INCLUDE 1
#define IGMPV3_MODE_IS_EXCLUDE 2
#define IGMPV3_CHANGE_TO_INCLUDE 3
#define IGMPV3_CHANGE_TO_EXCLUDE 4
#define IGMPV3_ALLOW_NEW_SOURCES 5
#define IGMPV3_BLOCK_OLD_SOURCES 6

//Support iGMPv3 w/o support 'grec_src[]'!
//From <linux/igmp.h> all in BigEndian Format
/* V3 group record types [grec_type] */
#define IGMPV3_MODE_IS_INCLUDE 1
#define IGMPV3_MODE_IS_EXCLUDE 2
#define IGMPV3_CHANGE_TO_INCLUDE 3
#define IGMPV3_CHANGE_TO_EXCLUDE 4
#define IGMPV3_ALLOW_NEW_SOURCES 5
#define IGMPV3_BLOCK_OLD_SOURCES 6
struct igmpv3_grec {
u_int8_t grec_type;
u_int8_t grec_auxwords;
u_int16_t grec_nsrcs;
u_int32 grec_mca;
u_int32 grec_src[0];
};
struct igmpv3_report {
u_int8_t type;
u_int8_t resv1;
u_int16_t csum;
u_int16_t resv2;
u_int16_t ngrec;
struct igmpv3_grec grec[0];
};
//#endif /*GIL_SUPPORT_IGMPV3*/

/*
* Exported variables.
*/
Expand Down Expand Up @@ -262,6 +298,48 @@ static void accept_igmp(ssize_t recvlen)
return;
}

//#ifdef GIL_SUPPORT_IGMPV3 //24Oct13
case IGMPV3_HOST_MEMBERSHIP_REPORT: //Join / Leave
{
int ngrec, grec_i;
char *NextGrecPtr;
struct igmpv3_report *igmpv3;
struct igmpv3_grec *Grec;

igmpv3 = (struct igmpv3_report *)(igmp_recv_buf + iphdrlen);
ngrec = ntohs(igmpv3->ngrec);

//logit(LOG_DEBUG, 0, "GIL 24OCT13 accept_igmp V3iGMP_Report type:0x%x src:%s dst:%s num_grp:%u",
// igmpv3->type, inet_fmt(src, s1, sizeof(s1)), inet_fmt(dst, s2, sizeof(s2)), ngrec );
Grec = &igmpv3->grec[0];
NextGrecPtr = (char *)Grec;
for (grec_i = 0; grec_i < ngrec; grec_i++)
{
u_int8_t grec_type = Grec->grec_type; //was: igmpv3->grec[grec_i].grec_type;
u_int16_t num_src = ntohs(Grec->grec_nsrcs); //was: ntohs(igmpv3->grec[grec_i].grec_nsrcs);

group = Grec->grec_mca; //Keep it in BigEndian/NetworkOrder //was: igmpv3->grec[grec_i].grec_mca;
//logit(LOG_DEBUG, 0, "..GIL 24OCT13 accept_igmp grec:%u type:%u #src:%u group:%s ptr-match:%u", grec_i, grec_type, num_src,
// inet_fmt(group, s2, sizeof(s2)), (NextGrecPtr==(char *)&igmpv3->grec[grec_i]) );
//Note "dst" is not as in IGMP_V1/V2 it is always 224.0.0.22, but it is ignored by the following callee
//Also type is only checked against IGMP_V1_MEMBERSHIP_REPORT or else...
//advance Grec for next loop!
NextGrecPtr += sizeof(struct igmpv3_grec); // Normal advance (i.e. for SOURCE EXCLUDE)
if (num_src > 1)
NextGrecPtr += (num_src - 1) * sizeof(u_int32); // adjust for grec_src[N]
Grec = (struct igmpv3_grec *)NextGrecPtr;

if (num_src != 0)
continue;
if ((grec_type == IGMPV3_MODE_IS_EXCLUDE) || (grec_type == IGMPV3_CHANGE_TO_EXCLUDE))
accept_group_report(src, dst, group, igmp->igmp_type);
else if (grec_type == IGMPV3_CHANGE_TO_INCLUDE)
accept_leave_message(src, dst, group);
}
}
return;
//#endif /*GIL_SUPPORT_IGMPV3*/

case IGMP_PIM:
return; /* TODO: this is PIM v1 message. Handle it?. */

Expand Down
13 changes: 13 additions & 0 deletions vif.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@


#include "defs.h"
//#ifdef GIL_SUPPORT_IGMPV3 //24Oct13 Add IGMPV3 Manage-Ip k_join/k_leave
#include <arpa/inet.h>
#define MCAST_ALL_IGMP_ROUTERS "224.0.0.22" //IGMPv3 Manage-Ip
//#endif /*GIL_SUPPORT_IGMPV3*/


/*
Expand Down Expand Up @@ -318,6 +322,12 @@ static void start_vif(vifi_t vifi)
*/
k_join(igmp_socket, allrouters_group, v);

//#ifdef GIL_SUPPORT_IGMPV3 //24Oct13 Add IGMPV3 Manage-Ip k_join/k_leave
/*
* TO support V3 MEMBERSHIP_REPORT need to join ALL-IGMP-ROUTERS
*/
k_join(igmp_socket, inet_addr(MCAST_ALL_IGMP_ROUTERS), v);
//#endif /*GIL_SUPPORT_IGMPV3*/
/*
* Until neighbors are discovered, assume responsibility for sending
* periodic group membership queries to the subnet. Send the first
Expand Down Expand Up @@ -368,6 +378,9 @@ static void stop_vif(vifi_t vifi)
if (!(v->uv_flags & VIFF_REGISTER)) {
k_leave(igmp_socket, allpimrouters_group, v);
k_leave(igmp_socket, allrouters_group, v);
//#ifdef GIL_SUPPORT_IGMPV3 //24Oct13 Add IGMPV3 Manage-Ip k_join/k_leave
k_leave(igmp_socket, inet_addr(MCAST_ALL_IGMP_ROUTERS), v);
//#endif /*GIL_SUPPORT_IGMPV3*/
/*
* Discard all group addresses. (No need to tell kernel;
* the k_del_vif() call will clean up kernel state.)
Expand Down

0 comments on commit 83c824f

Please sign in to comment.