Outgoing IGMP is functional

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2797 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2010-07-14 01:57:00 +00:00
parent 2926fe8f32
commit bb4a701c33
11 changed files with 145 additions and 31 deletions

View File

@ -1822,8 +1822,8 @@ static int ez80emac_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->d_private; FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->d_private;
/* Add the MAC address to the hardware multicast routing table */ /* Add the MAC address to the hardware multicast routing table */
/* MISSING LOGIC!!! */
#warning "Multicast MAC support not implemented"
return OK; return OK;
} }
#endif #endif
@ -1852,8 +1852,8 @@ static int ez80emac_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->d_private; FAR struct ez80emac_driver_s *priv = (FAR struct ez80emac_driver_s *)dev->d_private;
/* Add the MAC address to the hardware multicast routing table */ /* Add the MAC address to the hardware multicast routing table */
/* MISSING LOGIC!!! */
#warning "Multicast MAC support not implemented"
return OK; return OK;
} }
#endif #endif

View File

@ -41,6 +41,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdint.h> #include <stdint.h>
#include <errno.h>
#include <arch/board/board.h> #include <arch/board/board.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>

View File

@ -110,7 +110,6 @@
#define IS_SCHEDMSG(f) (((f) & IGMP_SCHEDMSG) != 0) #define IS_SCHEDMSG(f) (((f) & IGMP_SCHEDMSG) != 0)
#define IS_WAITMSG(f) (((f) & IGMP_WAITMSG) != 0) #define IS_WAITMSG(f) (((f) & IGMP_WAITMSG) != 0)
#define ROUTER_ALERT 0x94040000
#define IGMP_TTL 1 #define IGMP_TTL 1
/**************************************************************************** /****************************************************************************

View File

@ -75,8 +75,8 @@
# define IPOPT_TYPE_OPTION_SEC (2 << IPOPT_TYPE_OPTION_SHIFT) /* Security (RFC 791, 1108) */ # define IPOPT_TYPE_OPTION_SEC (2 << IPOPT_TYPE_OPTION_SHIFT) /* Security (RFC 791, 1108) */
# define IPOPT_TYPE_OPTION_LSRR (3 << IPOPT_TYPE_OPTION_SHIFT) /* Loose source and record route (RFC 791) */ # define IPOPT_TYPE_OPTION_LSRR (3 << IPOPT_TYPE_OPTION_SHIFT) /* Loose source and record route (RFC 791) */
# define IPOPT_TYPE_OPTION_TIMESTAMP (4 << IPOPT_TYPE_OPTION_SHIFT) /* Timestamp (RFC 781, 791) */ # define IPOPT_TYPE_OPTION_TIMESTAMP (4 << IPOPT_TYPE_OPTION_SHIFT) /* Timestamp (RFC 781, 791) */
# define IPORT_TYPE_OPTION_EXTSEC (5 << IPOPT_TYPE_OPTION_SHIFT) /* Extended security (RFC 1108) */ # define IPOPT_TYPE_OPTION_EXTSEC (5 << IPOPT_TYPE_OPTION_SHIFT) /* Extended security (RFC 1108) */
# define IPORT_TYPE_OPTION_COMMSEC (6 << IPOPT_TYPE_OPTION_SHIFT) /* Commercial security */ # define IPOPT_TYPE_OPTION_COMMSEC (6 << IPOPT_TYPE_OPTION_SHIFT) /* Commercial security */
# define IPOPT_TYPE_OPTION_RR (7 << IPOPT_TYPE_OPTION_SHIFT) /* Record route (RFC 791) */ # define IPOPT_TYPE_OPTION_RR (7 << IPOPT_TYPE_OPTION_SHIFT) /* Record route (RFC 791) */
# define IPOPT_TYPE_OPTION_SSID (8 << IPOPT_TYPE_OPTION_SHIFT) /* Stream ID (RFC 791, 1122) */ # define IPOPT_TYPE_OPTION_SSID (8 << IPOPT_TYPE_OPTION_SHIFT) /* Stream ID (RFC 791, 1122) */
# define IPOPT_TYPE_OPTION_SSRR (9 << IPOPT_TYPE_OPTION_SHIFT) /* Strict source and record route (RFC 791) */ # define IPOPT_TYPE_OPTION_SSRR (9 << IPOPT_TYPE_OPTION_SHIFT) /* Strict source and record route (RFC 791) */
@ -110,7 +110,7 @@
#define IPOPT_MKOPTION8(copied,class,option) \ #define IPOPT_MKOPTION8(copied,class,option) \
((uint8_t)IPOPT_MKTYPE(copied,class,option)) ((uint8_t)IPOPT_MKTYPE(copied,class,option))
#define IPOPT_MKOPTION32(type,len,ptr,data) \ #define IPOPT_MKOPTION32(type,len,ptr,data) \
((uint32_t)(type) << 24 | (uint32_t)(len) << 16) | \ ((uint32_t)(type) << 24 | (uint32_t)(len) << 16 | \
(uint32_t)(ptr) << 8 | (uint32_t)(data)) (uint32_t)(ptr) << 8 | (uint32_t)(data))
/* Option Copy Class Length Description References /* Option Copy Class Length Description References
@ -169,11 +169,11 @@
#define IPOPT_TIMESTAMP_TYPE \ #define IPOPT_TIMESTAMP_TYPE \
IPOPT_MKTYPE(IPOPT_TYPE_NOTCOPIED, IPOPT_TYPE_CLASS_MEASURE, IPOPT_TYPE_OPTION_TIMESTAMP) IPOPT_MKTYPE(IPOPT_TYPE_NOTCOPIED, IPOPT_TYPE_CLASS_MEASURE, IPOPT_TYPE_OPTION_TIMESTAMP)
#define IPORT_EXTSEC_TYPE \ #define IPOPT_EXTSEC_TYPE \
IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPORT_TYPE_OPTION_EXTSEC) IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_EXTSEC)
#define IPORT_COMMSEC_TYPE \ #define IPOPT_COMMSEC_TYPE \
IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPORT_TYPE_OPTION_COMMSEC) IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_COMMSEC)
#define IPOPT_RR_TYPE \ #define IPOPT_RR_TYPE \
IPOPT_MKTYPE(IPOPT_TYPE_NOTCOPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_RR) IPOPT_MKTYPE(IPOPT_TYPE_NOTCOPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_RR)
@ -222,7 +222,7 @@
#define IPOPT_RA_TYPE \ #define IPOPT_RA_TYPE \
IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_RA) IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_RA)
#define IPOPT_RA \ #define IPOPT_RA \
IPOPT_MKOPTION32(IPORT_RA_TYPE, 4, 0, 0) IPOPT_MKOPTION32(IPOPT_RA_TYPE, 4, 0, 0)
#define IPOPT_SDBM_TYPE \ #define IPOPT_SDBM_TYPE \
IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_SDBM) IPOPT_MKTYPE(IPOPT_TYPE_COPIED, IPOPT_TYPE_CLASS_CTRL, IPOPT_TYPE_OPTION_SDBM)

View File

@ -442,7 +442,7 @@ extern void uip_send(struct uip_driver_s *dev, const void *buf, int len);
* uip_ipaddr_t ipaddr1, ipaddr2; * uip_ipaddr_t ipaddr1, ipaddr2;
* *
* uip_ipaddr(&ipaddr1, 192,16,1,2); * uip_ipaddr(&ipaddr1, 192,16,1,2);
* if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { * if(uip_ipaddr_cmp(ipaddr2, ipaddr1)) {
* printf("They are the same"); * printf("They are the same");
* } * }
* *

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* net/uip/uip_icmsend.c * net/uip/uip_icmpsend.c
* *
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. * Copyright (C) 2008-2010 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -43,9 +43,11 @@
****************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <wdog.h>
#include <queue.h> #include <queue.h>
#include <debug.h> #include <debug.h>
@ -64,6 +66,8 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* Configuration ************************************************************/
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
# error "IGMP for IPv6 not supported" # error "IGMP for IPv6 not supported"
#endif #endif
@ -72,6 +76,40 @@
# define CONFIG_PREALLOC_IGMPGROUPS 4 # define CONFIG_PREALLOC_IGMPGROUPS 4
#endif #endif
/* Debug ********************************************************************/
#undef IGMP_GRPDEBUG /* Define to enable detailed IGMP group debug */
#ifndef CONFIG_NET_IGMP
# undef IGMP_GRPDEBUG
#endif
#ifdef CONFIG_CPP_HAVE_VARARGS
# ifdef IGMP_GRPDEBUG
# define grpdbg(format, arg...) ndbg(format, ##arg)
# define grplldbg(format, arg...) nlldbg(format, ##arg)
# define grpvdbg(format, arg...) nvdbg(format, ##arg)
# define grpllvdbg(format, arg...) nllvdbg(format, ##arg)
# else
# define grpdbg(x...)
# define grplldbg(x...)
# define grpvdbg(x...)
# define grpllvdbg(x...)
# endif
#else
# ifdef IGMP_GRPDEBUG
# define grpdbg ndbg
# define grplldbg nlldbg
# define grpvdbg nvdbg
# define grpllvdbg nllvdbg
# else
# define grpdbg (void)
# define grplldbg (void)
# define grpvdbg (void)
# define grpllvdbg (void)
# endif
#endif
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
@ -151,6 +189,8 @@ void uip_grpinit(void)
FAR struct igmp_group_s *group; FAR struct igmp_group_s *group;
int i; int i;
grplldbg("Initializing\n");
for (i = 0; i < CONFIG_PREALLOC_IGMPGROUPS; i++) for (i = 0; i < CONFIG_PREALLOC_IGMPGROUPS; i++)
{ {
group = &g_preallocgrps[i]; group = &g_preallocgrps[i];
@ -178,12 +218,15 @@ FAR struct igmp_group_s *uip_grpalloc(FAR struct uip_driver_s *dev,
nllvdbg("addr: %08x dev: %p\n", *addr, dev); nllvdbg("addr: %08x dev: %p\n", *addr, dev);
if (up_interrupt_context()) if (up_interrupt_context())
{ {
grplldbg("Allocate from the heap\n");
group = uip_grpheapalloc(); group = uip_grpheapalloc();
} }
else else
{ {
grplldbg("Use a pre-allocated group entry\n");
group = uip_grpprealloc(); group = uip_grpprealloc();
} }
grplldbg("group: %p\n", group);
/* Check if we succesfully allocated a group structure */ /* Check if we succesfully allocated a group structure */
@ -194,6 +237,11 @@ FAR struct igmp_group_s *uip_grpalloc(FAR struct uip_driver_s *dev,
uip_ipaddr_copy(group->grpaddr, *addr); uip_ipaddr_copy(group->grpaddr, *addr);
sem_init(&group->sem, 0, 0); sem_init(&group->sem, 0, 0);
/* Initialize the group timer (but don't start it yet) */
group->wdog = wd_create();
DEBUGASSERT(group->wdog);
/* Interrupts must be disabled in order to modify the group list */ /* Interrupts must be disabled in order to modify the group list */
flags = irqsave(); flags = irqsave();
@ -223,15 +271,21 @@ FAR struct igmp_group_s *uip_grpfind(FAR struct uip_driver_s *dev,
FAR struct igmp_group_s *group; FAR struct igmp_group_s *group;
irqstate_t flags; irqstate_t flags;
/* We must disable interrupts because we don't which context we were called grplldbg("Searching for addr %08x\n", (int)*addr);
* from.
/* We must disable interrupts because we don't which context we were
* called from.
*/ */
flags = irqsave(); flags = irqsave();
for (group = (FAR struct igmp_group_s *)dev->grplist.head; group; group = group->next) for (group = (FAR struct igmp_group_s *)dev->grplist.head;
group;
group = group->next)
{ {
if (uip_ipaddr_cmp(&group->grpaddr, *addr)) grplldbg("Compare: %08x vs. %08x\n", group->grpaddr, *addr);
if (uip_ipaddr_cmp(group->grpaddr, *addr))
{ {
grplldbg("Match!\n");
break; break;
} }
} }
@ -255,10 +309,13 @@ FAR struct igmp_group_s *uip_grpallocfind(FAR struct uip_driver_s *dev,
FAR const uip_ipaddr_t *addr) FAR const uip_ipaddr_t *addr)
{ {
FAR struct igmp_group_s *group = uip_grpfind(dev, addr); FAR struct igmp_group_s *group = uip_grpfind(dev, addr);
grplldbg("group: %p addr: %08x\n", group, (int)*addr);
if (!group) if (!group)
{ {
group = uip_grpalloc(dev, addr); group = uip_grpalloc(dev, addr);
} }
grplldbg("group: %p\n", group);
return group; return group;
} }
@ -275,23 +332,34 @@ FAR struct igmp_group_s *uip_grpallocfind(FAR struct uip_driver_s *dev,
void uip_grpfree(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group) void uip_grpfree(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group)
{ {
/* First, remove the group structure from the group list in the device irqstate_t flags;
* structure
*/ grplldbg("Free: %p flags: %02x\n", group, group->flags);
/* Cancel the wdog */
flags = irqsave();
wd_cancel(group->wdog);
/* Remove the group structure from the group list in the device structure */
irqstate_t flags = irqsave();
sq_rem((FAR sq_entry_t*)group, &dev->grplist); sq_rem((FAR sq_entry_t*)group, &dev->grplist);
/* Destroy the wait semapore */ /* Destroy the wait semapore */
(void)sem_destroy(&group->sem); (void)sem_destroy(&group->sem);
/* Destroy the wdog */
wd_delete(group->wdog);
/* Then release the group structure resources. Check first if this is one /* Then release the group structure resources. Check first if this is one
* of the pre-allocated group structures that we will retain in a free list. * of the pre-allocated group structures that we will retain in a free list.
*/ */
if (IS_PREALLOCATED(group->flags)) if (IS_PREALLOCATED(group->flags))
{ {
grplldbg("Put back on free list\n");
sq_addlast((FAR sq_entry_t*)group, &g_freelist); sq_addlast((FAR sq_entry_t*)group, &g_freelist);
irqrestore(flags); irqrestore(flags);
} }
@ -302,6 +370,7 @@ void uip_grpfree(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group)
*/ */
irqrestore(flags); irqrestore(flags);
grplldbg("Call sched_free()\n");
sched_free(group); sched_free(group);
} }
} }

View File

@ -44,7 +44,6 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <wdog.h>
#include <assert.h> #include <assert.h>
#include <debug.h> #include <debug.h>
@ -113,10 +112,6 @@ void uip_igmpdevinit(struct uip_driver_s *dev)
group = uip_grpalloc(dev, &g_allsystems); group = uip_grpalloc(dev, &g_allsystems);
/* Initialize the group timer (but don't start it yet) */
group->wdog = wd_create();
/* Allow the IGMP messages at the MAC level */ /* Allow the IGMP messages at the MAC level */
uip_addmcastmac(dev, &g_allrouters); uip_addmcastmac(dev, &g_allrouters);

View File

@ -158,7 +158,7 @@ int igmp_leavegroup(struct uip_driver_s *dev, FAR const struct in_addr *grpaddr)
if (IS_LASTREPORT(group->flags)) if (IS_LASTREPORT(group->flags))
{ {
ndbg("Schedul Leave Group message\n"); ndbg("Schedule Leave Group message\n");
IGMP_STATINCR(uip_stat.igmp.leave_sched); IGMP_STATINCR(uip_stat.igmp.leave_sched);
uip_igmpwaitmsg(group, IGMP_LEAVE_GROUP); uip_igmpwaitmsg(group, IGMP_LEAVE_GROUP);
} }

View File

@ -45,6 +45,7 @@
#include <net/uip/uipopt.h> #include <net/uip/uipopt.h>
#include <net/uip/uip.h> #include <net/uip/uip.h>
#include <net/uip/uip-arch.h> #include <net/uip/uip-arch.h>
#include <net/uip/uip-ipopt.h>
#include <net/uip/uip-igmp.h> #include <net/uip/uip-igmp.h>
#include "uip_internal.h" #include "uip_internal.h"
@ -134,8 +135,8 @@ void uip_igmpsend(FAR struct uip_driver_s *dev, FAR struct igmp_group_s *group,
/* Add the router alert option */ /* Add the router alert option */
IGMPBUF->ra[0] = HTONS(ROUTER_ALERT >> 16); IGMPBUF->ra[0] = HTONS(IPOPT_RA >> 16);
IGMPBUF->ra[1] = HTONS(ROUTER_ALERT & 0xffff); IGMPBUF->ra[1] = HTONS(IPOPT_RA & 0xffff);
/* Initialize the IPv4 header */ /* Initialize the IPv4 header */

View File

@ -42,6 +42,7 @@
****************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <wdog.h> #include <wdog.h>
#include <assert.h> #include <assert.h>
@ -59,6 +60,40 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* Debug ********************************************************************/
#undef IGMP_GTMRDEBUG /* Define to enable detailed IGMP group debug */
#ifndef CONFIG_NET_IGMP
# undef IGMP_GTMRDEBUG
#endif
#ifdef CONFIG_CPP_HAVE_VARARGS
# ifdef IGMP_GTMRDEBUG
# define gtmrdbg(format, arg...) ndbg(format, ##arg)
# define gtmrlldbg(format, arg...) nlldbg(format, ##arg)
# define gtmrvdbg(format, arg...) nvdbg(format, ##arg)
# define gtmrllvdbg(format, arg...) nllvdbg(format, ##arg)
# else
# define gtmrdbg(x...)
# define gtmrlldbg(x...)
# define gtmrvdbg(x...)
# define gtmrllvdbg(x...)
# endif
#else
# ifdef IGMP_GTMRDEBUG
# define gtmrdbg ndbg
# define gtmrlldbg nlldbg
# define gtmrvdbg nvdbg
# define gtmrllvdbg nllvdbg
# else
# define gtmrdbg (void)
# define gtmrlldbg (void)
# define gtmrvdbg (void)
# define gtmrllvdbg (void)
# endif
#endif
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -100,6 +135,14 @@ static void uip_igmptimeout(int argc, uint32_t arg, ...)
IGMP_STATINCR(uip_stat.igmp.report_sched); IGMP_STATINCR(uip_stat.igmp.report_sched);
uip_igmpschedmsg(group, IGMPv2_MEMBERSHIP_REPORT); uip_igmpschedmsg(group, IGMPv2_MEMBERSHIP_REPORT);
/* Also note: The Membership Report is sent at most two times becasue
* the timer is not reset here. Hmm.. does this mean that the group
* is stranded if both reports were lost? This is consistent with the
* RFC that states: "To cover the possibility of the initial Membership
* Report being lost or damaged, it is recommended that it be repeated
* once or twice after shortdelays [Unsolicited Report Interval]..."
*/
} }
} }
@ -142,9 +185,13 @@ int uip_decisec2tick(int decisecs)
void uip_igmpstartticks(FAR struct igmp_group_s *group, int ticks) void uip_igmpstartticks(FAR struct igmp_group_s *group, int ticks)
{ {
int ret;
/* Start the timer */ /* Start the timer */
wd_start(group->wdog, ticks, uip_igmptimeout, 1, (uint32_t)group); gtmrlldbg("ticks: %d\n", ticks);
ret = wd_start(group->wdog, ticks, uip_igmptimeout, 1, (uint32_t)group);
DEBUGASSERT(ret == OK);
} }
void uip_igmpstarttimer(FAR struct igmp_group_s *group, uint8_t decisecs) void uip_igmpstarttimer(FAR struct igmp_group_s *group, uint8_t decisecs)
@ -153,6 +200,7 @@ void uip_igmpstarttimer(FAR struct igmp_group_s *group, uint8_t decisecs)
* Important!! this should be a random timer from 0 to decisecs * Important!! this should be a random timer from 0 to decisecs
*/ */
gtmrdbg("decisecs: %d\n", decisecs);
uip_igmpstartticks(group, uip_decisec2tick(decisecs)); uip_igmpstartticks(group, uip_decisec2tick(decisecs));
} }
@ -192,6 +240,7 @@ bool uip_igmpcmptimer(FAR struct igmp_group_s *group, int maxticks)
* test as well. * test as well.
*/ */
gtmrdbg("maxticks: %d remaining: %d\n", maxticks, remaining);
if (maxticks > remaining) if (maxticks > remaining)
{ {
/* Cancel the watchdog timer and return true */ /* Cancel the watchdog timer and return true */