mcast-tools: add initial port

This commit is contained in:
Steven Barth 2014-04-10 19:03:29 +02:00
parent 4dd022ad96
commit c0eb80e736
6 changed files with 547 additions and 0 deletions

62
mcast-tools/Makefile Normal file
View File

@ -0,0 +1,62 @@
#
# Copyright (C) 2014 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=mcast-tools
PKG_SOURCE_VERSION:=e5c860f174c6deb4cc30211e895831aca0a55b7f
PKG_VERSION:=2014-04-06
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/F0rth/mcast-tools.git
PKG_MAINTAINER:=Steven Barth <cyrus@openwrt.org>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
CONFIGURE_ARGS+=--enable-mldv2host --disable-pim6dd --disable-mcastread --disable-mcastsend --disable-mfc --disable-mtrace6 --disable-pmsft
TARGET_CFLAGS+=-DIP6OPT_RTALERT_LEN=4 -D_GNU_SOURCE
define Package/pim6sd
SECTION:=net
CATEGORY:=Network
SUBMENU:=Routing and Redirection
TITLE:=Sparse PIM IPv6 Multicast Routing Daemon
endef
define Package/pim6sd/description
pim6sd is an IPv6 multicast routing daemon, which supports PIMv2(Protocol
Independent Multicast Version 2) sparse mode and SSM(Source-Specific-
Multicast) for IPv6.
endef
define Package/pim6sd/conffiles
/etc/pim6sd.conf
endef
define Build/Prepare
$(call Build/Prepare/Default)
( cd $(PKG_BUILD_DIR) ; \
aclocal ; \
autoheader ; \
automake --add-missing; \
autoconf ; \
)
endef
define Package/pim6sd/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_CONF) ./files/pim6sd.conf $(1)/etc
$(INSTALL_BIN) ./files/pim6sd.init $(1)/etc/init.d/pim6sd
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/pim6sd/pim6sd $(1)/usr/sbin/pim6sd
endef
$(eval $(call BuildPackage,pim6sd))

View File

@ -0,0 +1,105 @@
#The timer granularity.
#More this value is small,more pim6sd will be accurate
#default if not specified : 5
#BE SURE to have to same granularity on ALL routers,
#otherwise....
#granularity 5;
#syntax : phyint <interface> <disable> <metric> [metric] <preference> [preference]
#metric and pref are for the asserts messages
#samples :
#phyint ed1 disable;
#phyint de0 disable;
#phyint ed0 disable;
#phyint gif0 disable;
#---------------Protocol timer specifications---------------------------#
#Notes : theses value are the default spec value!
#do not touch it if you don't know what you do!!
#you MUST change theses values according to the granularity value!
#syntax : 'hello_period <number> <coef>'.
# number is the period in second between 2 hello messages
# and coef is the coef to determine the hello holdtime=hello_period*coef
# default if not specified: 30 3.5
#hello_period 30 3.5;
#syntax : 'join_prune_period <number> <coef>'.
# number is the period in second between 2 join/prune messages
# and coef is the coef to determine the join/prune holdtime=join_prune_period*coef
# default if not specified : 60 3.5
#join_prune_period 60 3.5;
#syntax : 'data_timeout <number>'.
# number is the time after which (S,G) state for a silent source will be deleted
# default if not specified : 210
#data_timeout 210;
#syntax : 'register_suppression_timeout <number>'.
# This is the mean interval between receiving a Register-Stop and allowing
#Register to be send again.
# default if not specified : 60
#register_suppression_timeout 60;
#syntax : 'probe_time <number>'.
#This is the time between sending a null Register and the Register-Suppression-Timer
#expiring unless it is restarted by receiving a Register-Stop.
#default if not specified : 5
#probe_time 5;
#syntax : 'assert_timeout <number>'.
#this is the interval between the last time an Assert is received and the time at which the
#assert is timeout
#default if not specified : 180
#assert_timeout 180;
#syntax : <cand_rp> <interface> <time> [time] <priority> [priority]
#and time can't be < 10
#you can just type cand_rp,
#samples :
#cand_rp;
#cand_rp de0;
#cand_rp ed0 priority 0 time 6;
#syntax : <group_prefix> <multicast address>/<prefix length>
#group_prefix ff06::15
#default if not specified : ff00::/8
#samples:
#group_prefix ff1e::15/128;
#group_prefix ff2e::/16;
#syntax : <cand_bootstrap_router> <interface> <priority> [priority] <time> [time]
#Typically, you can simply set cand_bootstrap_router for a candidate bootstrap
#router. All other parameters are optional.
#the bootstrap period is configurable, BUT the holdtime of a bootstrap
#router is not in the fields of a bootstrap message : it is hard-coded
#in the pim6sd include file!
#So be sure to have a time < PIM_BOOTSTRAP_TIMEOUT (file pimd.h )
#cand_bootstrap_router de0 priority 15 time 5;
#syntax : <switch_register_threshold> <rate> [number] <interval> [number]
#default rate = 50000 interval = 20s
#samples :
#TODO : not tested
#switch_register_threshold rate 54389 interval 45;
#switch_register_threshold;
#syntax : <switch_data_threshold> <rate> [number] <interval> [number]
#default rate = 50000 interval = 20s
#TODO : not tested
#samples:
#switch_data_threshold interval 100 rate 1000;
#syntax : <default_source_metric> [number]
#default_source_metric 1243;
#syntax : <default_source_preference> [number]
#default_source_preference 123 ;

View File

@ -0,0 +1,14 @@
#!/bin/sh /etc/rc.common
START=50
USE_PROCD=1
start_service() {
procd_open_instance
procd_set_param command /usr/sbin/pim6sd
procd_append_param command -f -c /etc/pim6sd.conf
procd_set_param respawn
procd_close_instance
}

View File

@ -0,0 +1,90 @@
From 179b60f9d6a8a104fd8d1f810d105ddba914cc7a Mon Sep 17 00:00:00 2001
From: Steven Barth <steven@midlink.org>
Date: Thu, 3 Apr 2014 09:09:06 +0200
Subject: [PATCH 1/3] Fix compilation on recent Linux
---
pim6sd/debug.c | 6 +++---
pim6sd/mld6.c | 8 ++++----
pim6sd/trace.c | 8 ++++++++
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/pim6sd/debug.c b/pim6sd/debug.c
index a06a876..a96e949 100644
--- a/pim6sd/debug.c
+++ b/pim6sd/debug.c
@@ -169,7 +169,7 @@ packet_kind(proto, type, code)
return "Multicast Listener Query ";
case MLD_LISTENER_REPORT:
return "Multicast Listener Report ";
- case MLD_LISTENER_DONE:
+ case MLD_LISTENER_REDUCTION:
return "Multicast Listener Done ";
default:
snprintf(unknown, sizeof(unknown),
@@ -230,7 +230,7 @@ debug_kind(proto, type, code)
return DEBUG_MLD;
case MLD_LISTENER_REPORT:
return DEBUG_MLD;
- case MLD_LISTENER_DONE:
+ case MLD_LISTENER_REDUCTION:
return DEBUG_MLD;
default:
return DEBUG_MLD;
@@ -574,7 +574,7 @@ dump_nbrs(fp)
if (n->options_bitmap & PIM_HELLO_GENID_BIT)
fprintf(fp, " %-8x", n->genid);
else
- fprintf(fp, " %-8x", "-");
+ fprintf(fp, " %-8s", "-");
if (v->uv_pim_dr == n)
fprintf(fp, " D");
fprintf(fp, "\n");
diff --git a/pim6sd/mld6.c b/pim6sd/mld6.c
index d828bbf..0bac85d 100644
--- a/pim6sd/mld6.c
+++ b/pim6sd/mld6.c
@@ -207,9 +207,9 @@ init_mld6()
/* filter all non-MLD ICMP messages */
ICMP6_FILTER_SETBLOCKALL(&filt);
- ICMP6_FILTER_SETPASS(ICMP6_MEMBERSHIP_QUERY, &filt);
- ICMP6_FILTER_SETPASS(ICMP6_MEMBERSHIP_REPORT, &filt);
- ICMP6_FILTER_SETPASS(ICMP6_MEMBERSHIP_REDUCTION, &filt);
+ ICMP6_FILTER_SETPASS(MLD_LISTENER_QUERY, &filt);
+ ICMP6_FILTER_SETPASS(MLD_LISTENER_REPORT, &filt);
+ ICMP6_FILTER_SETPASS(MLD_LISTENER_REDUCTION, &filt);
#ifdef MLD_MTRACE_RESP
ICMP6_FILTER_SETPASS(MLD_MTRACE_RESP, &filt);
ICMP6_FILTER_SETPASS(MLD_MTRACE, &filt);
@@ -448,7 +448,7 @@ accept_mld6(recvlen)
accept_listener_report(src, dst, group);
return;
- case MLD_LISTENER_DONE:
+ case MLD_LISTENER_REDUCTION:
accept_listener_done(src, dst, group);
return;
diff --git a/pim6sd/trace.c b/pim6sd/trace.c
index e361633..175c858 100644
--- a/pim6sd/trace.c
+++ b/pim6sd/trace.c
@@ -110,6 +110,14 @@
#include "rp.h"
#include "trace.h"
+#ifndef MLD_MTRACE_RESP
+# define MLD_MTRACE_RESP 200
+#endif
+
+#ifndef MLD_MTRACE
+# define MLD_MTRACE 201
+#endif
+
/* TODO */
/*
* Traceroute function which returns traceroute replies to the requesting
--
1.8.3.2

View File

@ -0,0 +1,49 @@
From 52e110289fcc0990688e16e640ca5e7f01c66bb1 Mon Sep 17 00:00:00 2001
From: Steven Barth <steven@midlink.org>
Date: Sun, 6 Apr 2014 17:46:42 +0200
Subject: [PATCH 23/23] Fix configure.in for cross-compilation
---
configure.in | 26 ++------------------------
1 file changed, 2 insertions(+), 24 deletions(-)
diff --git a/configure.in b/configure.in
index b8446e2..e626a19 100644
--- a/configure.in
+++ b/configure.in
@@ -170,30 +170,8 @@ fi
AC_MSG_RESULT($enable_mldv2host)
dnl Determine routing get and set method
-AC_MSG_CHECKING(userland-kernel interface for routing information)
-AC_TRY_RUN([#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-main ()
-{
-#ifdef AF_NETLINK
- exit(1);
-#else
- int ac_sock;
-
- ac_sock = socket (AF_ROUTE, SOCK_RAW, 0);
- if (ac_sock < 0 && errno == EINVAL)
- exit (1);
- exit (0);
-#endif
-}],
- [AC_DEFINE(HAVE_ROUTING_SOCKETS)
- UK_METHOD=routesock
- AC_MSG_RESULT(routing socket)],
- [AC_DEFINE(HAVE_NETLINK)
- UK_METHOD=netlink
- AC_MSG_RESULT(netlink)])
+AC_DEFINE(HAVE_NETLINK)
+UK_METHOD=netlink
AC_SUBST(UK_METHOD)
dnl Checks for RFC3542
--
1.9.1

View File

@ -0,0 +1,227 @@
From 50bcf257f5f7d359d06744128585103f19072ee3 Mon Sep 17 00:00:00 2001
From: Steven Barth <steven@midlink.org>
Date: Thu, 10 Apr 2014 18:56:53 +0200
Subject: [PATCH] Add compatibility code for uclibc
---
pim6sd/cftoken.l | 5 ++
pim6sd/inet6_compat.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++
pim6sd/mld6.c | 4 ++
pim6sd/mld6v2.c | 5 ++
4 files changed, 175 insertions(+)
create mode 100644 pim6sd/inet6_compat.c
diff --git a/pim6sd/cftoken.l b/pim6sd/cftoken.l
index 17479d0..5b20741 100644
--- a/pim6sd/cftoken.l
+++ b/pim6sd/cftoken.l
@@ -697,3 +697,8 @@ cfparse(strict, debugonly)
return cf_post_config();
}
+
+int yywrap(void)
+{
+ return 1;
+}
diff --git a/pim6sd/inet6_compat.c b/pim6sd/inet6_compat.c
new file mode 100644
index 0000000..375f17f
--- /dev/null
+++ b/pim6sd/inet6_compat.c
@@ -0,0 +1,161 @@
+#include <assert.h>
+
+static void
+add_pad (struct cmsghdr *cmsg, int len)
+{
+ unsigned char *p = CMSG_DATA (cmsg) + cmsg->cmsg_len - CMSG_LEN (0);
+
+ if (len == 1)
+ /* Special handling for 1, a one-byte solution. */
+ *p++ = IP6OPT_PAD1;
+ else if (len != 0)
+ {
+ /* Multibyte padding. */
+ *p++ = IP6OPT_PADN;
+ *p++ = len - 2; /* Discount the two header bytes. */
+ /* The rest is filled with zero. */
+ memset (p, '\0', len - 2);
+ p += len - 2;
+ }
+
+ /* Account for the bytes. */
+ cmsg->cmsg_len += len;
+}
+
+
+/* RFC 2292, 6.3.4
+
+ This function appends a Hop-by-Hop option or a Destination option
+ into an ancillary data object that has been initialized by
+ inet6_option_init(). This function returns a pointer to the 8-bit
+ option type field that starts the option on success, or NULL on an
+ error. */
+static uint8_t *
+option_alloc (struct cmsghdr *cmsg, int datalen, int multx, int plusy)
+{
+ /* The RFC limits the value of the alignment values. */
+ if ((multx != 1 && multx != 2 && multx != 4 && multx != 8)
+ || ! (plusy >= 0 && plusy <= 7))
+ return NULL;
+
+ /* Current data size. */
+ int dsize = cmsg->cmsg_len - CMSG_LEN (0);
+
+ /* The first two bytes of the option are for the extended header. */
+ if (__builtin_expect (dsize == 0, 0))
+ {
+ cmsg->cmsg_len += sizeof (struct ip6_ext);
+ dsize = sizeof (struct ip6_ext);
+ }
+
+ /* First add padding. */
+ add_pad (cmsg, ((multx - (dsize & (multx - 1))) & (multx - 1)) + plusy);
+
+ /* Return the pointer to the start of the option space. */
+ uint8_t *result = CMSG_DATA (cmsg) + cmsg->cmsg_len - CMSG_LEN (0);
+ cmsg->cmsg_len += datalen;
+
+ /* The extended option header length is measured in 8-byte groups.
+ To represent the current length we might have to add padding. */
+ dsize = cmsg->cmsg_len - CMSG_LEN (0);
+ add_pad (cmsg, (8 - (dsize & (8 - 1))) & (8 - 1));
+
+ /* Record the new length of the option. */
+ assert (((cmsg->cmsg_len - CMSG_LEN (0)) % 8) == 0);
+ int len8b = (cmsg->cmsg_len - CMSG_LEN (0)) / 8 - 1;
+ if (len8b >= 256)
+ /* Too long. */
+ return NULL;
+
+ struct ip6_ext *ie = (void *) CMSG_DATA (cmsg);
+ ie->ip6e_len = len8b;
+
+ return result;
+}
+
+
+/* RFC 2292, 6.3.1
+
+ This function returns the number of bytes required to hold an option
+ when it is stored as ancillary data, including the cmsghdr structure
+ at the beginning, and any padding at the end (to make its size a
+ multiple of 8 bytes). The argument is the size of the structure
+ defining the option, which must include any pad bytes at the
+ beginning (the value y in the alignment term "xn + y"), the type
+ byte, the length byte, and the option data. */
+static int
+inet6_option_space (nbytes)
+ int nbytes;
+{
+ /* Add room for the extension header. */
+ nbytes += sizeof (struct ip6_ext);
+
+ return CMSG_SPACE (roundup (nbytes, 8));
+}
+
+
+/* RFC 2292, 6.3.2
+
+ This function is called once per ancillary data object that will
+ contain either Hop-by-Hop or Destination options. It returns 0 on
+ success or -1 on an error. */
+static int
+inet6_option_init (bp, cmsgp, type)
+ void *bp;
+ struct cmsghdr **cmsgp;
+ int type;
+{
+ /* Only Hop-by-Hop or Destination options allowed. */
+ if (type != IPV6_HOPOPTS && type != IPV6_DSTOPTS)
+ return -1;
+
+ /* BP is a pointer to the previously allocated space. */
+ struct cmsghdr *newp = (struct cmsghdr *) bp;
+
+ /* Initialize the message header.
+
+ Length: No data yet, only the cmsghdr struct. */
+ newp->cmsg_len = CMSG_LEN (0);
+ /* Originating protocol: obviously IPv6. */
+ newp->cmsg_level = IPPROTO_IPV6;
+ /* Message type. */
+ newp->cmsg_type = type;
+
+ /* Pass up the result. */
+ *cmsgp = newp;
+
+ return 0;
+}
+
+
+/* RFC 2292, 6.3.3
+
+ This function appends a Hop-by-Hop option or a Destination option
+ into an ancillary data object that has been initialized by
+ inet6_option_init(). This function returns 0 if it succeeds or -1 on
+ an error. */
+static int
+inet6_option_append (cmsg, typep, multx, plusy)
+ struct cmsghdr *cmsg;
+ const uint8_t *typep;
+ int multx;
+ int plusy;
+{
+ /* typep is a pointer to the 8-bit option type. It is assumed that this
+ field is immediately followed by the 8-bit option data length field,
+ which is then followed immediately by the option data.
+
+ The option types IP6OPT_PAD1 and IP6OPT_PADN also must be handled. */
+ int len = typep[0] == IP6OPT_PAD1 ? 1 : typep[1] + 2;
+
+ /* Get the pointer to the space in the message. */
+ uint8_t *ptr = option_alloc (cmsg, len, multx, plusy);
+ if (ptr == NULL)
+ /* Some problem with the parameters. */
+ return -1;
+
+ /* Copy the content. */
+ memcpy (ptr, typep, len);
+
+ return 0;
+}
diff --git a/pim6sd/mld6.c b/pim6sd/mld6.c
index 0bac85d..febdc98 100644
--- a/pim6sd/mld6.c
+++ b/pim6sd/mld6.c
@@ -108,6 +108,10 @@
#include "trace.h"
#include "mld6.h"
+#ifdef __UCLIBC__
+#include "inet6_compat.c"
+#endif
+
/*
* Exported variables.
*/
diff --git a/pim6sd/mld6v2.c b/pim6sd/mld6v2.c
index 8cd5a4d..322cb7b 100644
--- a/pim6sd/mld6v2.c
+++ b/pim6sd/mld6v2.c
@@ -73,6 +73,11 @@
#include "callout.h"
#include "timer.h"
+#ifdef __UCLIBC__
+#include "inet6_compat.c"
+#endif
+
+
#ifdef HAVE_MLDV2
#ifndef HAVE_RFC3542
--
1.9.1