diff options
author | glebius <glebius@FreeBSD.org> | 2005-02-12 11:41:32 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2005-02-12 11:41:32 +0000 |
commit | 0382724fd953dcd5d794a85e6099ac9d9fdd1663 (patch) | |
tree | 30374dc3c16bce7743363d885b0b8cd23322a338 /sys/netgraph/ng_ether.c | |
parent | 03b8abc87714fb6328d3cdd33f74a266f1aa84c6 (diff) | |
download | FreeBSD-src-0382724fd953dcd5d794a85e6099ac9d9fdd1663.zip FreeBSD-src-0382724fd953dcd5d794a85e6099ac9d9fdd1663.tar.gz |
Add two new netgraph messages NGM_ETHER_ADD_MULTI and NGM_ETHER_DEL_MULTI,
to join and leave Ethernet multicast membership, respectively. Messages
take MAC address as argument.
Sponsored by: Rinet ISP
Diffstat (limited to 'sys/netgraph/ng_ether.c')
-rw-r--r-- | sys/netgraph/ng_ether.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c index 674a1f2..cfa0976 100644 --- a/sys/netgraph/ng_ether.c +++ b/sys/netgraph/ng_ether.c @@ -57,6 +57,7 @@ #include <net/bridge.h> #include <net/if.h> +#include <net/if_dl.h> #include <net/if_types.h> #include <net/if_arp.h> #include <net/if_var.h> @@ -171,6 +172,20 @@ static const struct ng_cmdlist ng_ether_cmdlist[] = { &ng_parse_int32_type, NULL }, + { + NGM_ETHER_COOKIE, + NGM_ETHER_ADD_MULTI, + "addmulti", + &ng_parse_enaddr_type, + NULL + }, + { + NGM_ETHER_COOKIE, + NGM_ETHER_DEL_MULTI, + "delmulti", + &ng_parse_enaddr_type, + NULL + }, { 0 } }; @@ -492,6 +507,47 @@ ng_ether_rcvmsg(node_p node, item_p item, hook_p lasthook) } priv->autoSrcAddr = !!*((u_int32_t *)msg->data); break; + case NGM_ETHER_ADD_MULTI: + { + struct sockaddr_dl sa_dl; + struct ifmultiaddr *ifm; + + if (msg->header.arglen != ETHER_ADDR_LEN) { + error = EINVAL; + break; + } + sa_dl.sdl_len = sizeof(struct sockaddr_dl); + sa_dl.sdl_family = AF_LINK; + sa_dl.sdl_index = 0; + sa_dl.sdl_nlen = 0; + sa_dl.sdl_alen = 6; + sa_dl.sdl_slen = 0; + bcopy((void *)msg->data, LLADDR(&sa_dl), + ETHER_ADDR_LEN); + error = if_addmulti(priv->ifp, + (struct sockaddr *)&sa_dl, &ifm); + break; + } + case NGM_ETHER_DEL_MULTI: + { + struct sockaddr_dl sa_dl; + + if (msg->header.arglen != ETHER_ADDR_LEN) { + error = EINVAL; + break; + } + sa_dl.sdl_len = sizeof(struct sockaddr_dl); + sa_dl.sdl_family = AF_LINK; + sa_dl.sdl_index = 0; + sa_dl.sdl_nlen = 0; + sa_dl.sdl_alen = 6; + sa_dl.sdl_slen = 0; + bcopy((void *)msg->data, LLADDR(&sa_dl), + ETHER_ADDR_LEN); + error = if_delmulti(priv->ifp, + (struct sockaddr *)&sa_dl); + break; + } default: error = EINVAL; break; |