* [PATCH][IPv6] Export userland ND options through netlink (RDNSS support)
@ 2007-10-05 6:09 Pierre Ynard
2007-10-11 4:22 ` David Miller
2010-12-02 22:59 ` David Woodhouse
0 siblings, 2 replies; 3+ messages in thread
From: Pierre Ynard @ 2007-10-05 6:09 UTC (permalink / raw)
To: netdev
As discussed before, this patch provides userland with a way to access
relevant options in Router Advertisements, after they are processed and
validated by the kernel. Extra options are processed in a generic way;
this patch only exports RDNSS options described in RFC5006, but support
to control which options are exported could be easily added.
A new rtnetlink message type is defined, to transport Neighbor Discovery
options, along with optional context information. At the moment only
the address of the router sending an RDNSS option is included, but
additional attributes may be later defined, if needed by new use cases.
Signed-off-by: Pierre Ynard <linkfanel@yahoo.fr>
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index dff3192..124d451 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -97,6 +97,9 @@ enum {
RTM_SETNEIGHTBL,
#define RTM_SETNEIGHTBL RTM_SETNEIGHTBL
+ RTM_NEWNDUSEROPT = 68,
+#define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT
+
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
@@ -479,6 +482,30 @@ enum
#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
+/********************************************************************
+ * Neighbor Discovery userland options
+ ****/
+
+struct nduseroptmsg
+{
+ unsigned char nduseropt_family;
+ unsigned char nduseropt_pad1;
+ unsigned short nduseropt_opts_len; /* Total length of options */
+ __u8 nduseropt_icmp_type;
+ __u8 nduseropt_icmp_code;
+ unsigned short nduseropt_pad2;
+ /* Followed by one or more ND options */
+};
+
+enum
+{
+ NDUSEROPT_UNSPEC,
+ NDUSEROPT_SRCADDR,
+ __NDUSEROPT_MAX
+};
+
+#define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1)
+
#ifndef __KERNEL__
/* RTnetlink multicast groups - backwards compatibility for userspace */
#define RTMGRP_LINK 1
@@ -542,6 +569,8 @@ enum rtnetlink_groups {
#define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX
RTNLGRP_IPV6_RULE,
#define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE
+ RTNLGRP_ND_USEROPT,
+#define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT
__RTNLGRP_MAX
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 475b10c..6684f7e 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -24,6 +24,7 @@ enum {
ND_OPT_MTU = 5, /* RFC2461 */
__ND_OPT_ARRAY_MAX,
ND_OPT_ROUTE_INFO = 24, /* RFC4191 */
+ ND_OPT_RDNSS = 25, /* RFC5006 */
__ND_OPT_MAX
};
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 74c4d8d..04b2453 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -15,9 +15,10 @@
/*
* Changes:
*
+ * Pierre Ynard : export userland ND options
+ * through netlink (RDNSS support)
* Lars Fenneberg : fixed MTU setting on receipt
* of an RA.
- *
* Janos Farkas : kmalloc failure checks
* Alexey Kuznetsov : state machine reworked
* and moved to net/core.
@@ -78,6 +79,9 @@
#include <net/addrconf.h>
#include <net/icmp.h>
+#include <net/netlink.h>
+#include <linux/rtnetlink.h>
+
#include <net/flow.h>
#include <net/ip6_checksum.h>
#include <linux/proc_fs.h>
@@ -161,6 +165,8 @@ struct ndisc_options {
struct nd_opt_hdr *nd_opts_ri;
struct nd_opt_hdr *nd_opts_ri_end;
#endif
+ struct nd_opt_hdr *nd_useropts;
+ struct nd_opt_hdr *nd_useropts_end;
};
#define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
@@ -225,6 +231,22 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
return (cur <= end && cur->nd_opt_type == type ? cur : NULL);
}
+static inline int ndisc_is_useropt(struct nd_opt_hdr *opt)
+{
+ return (opt->nd_opt_type == ND_OPT_RDNSS);
+}
+
+static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur,
+ struct nd_opt_hdr *end)
+{
+ if (!cur || !end || cur >= end)
+ return NULL;
+ do {
+ cur = ((void *)cur) + (cur->nd_opt_len << 3);
+ } while(cur < end && !ndisc_is_useropt(cur));
+ return (cur <= end && ndisc_is_useropt(cur) ? cur : NULL);
+}
+
static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
struct ndisc_options *ndopts)
{
@@ -267,14 +289,21 @@ static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
break;
#endif
default:
- /*
- * Unknown options must be silently ignored,
- * to accommodate future extension to the protocol.
- */
- ND_PRINTK2(KERN_NOTICE
- "%s(): ignored unsupported option; type=%d, len=%d\n",
- __FUNCTION__,
- nd_opt->nd_opt_type, nd_opt->nd_opt_len);
+ if (ndisc_is_useropt(nd_opt)) {
+ ndopts->nd_useropts_end = nd_opt;
+ if (!ndopts->nd_useropts)
+ ndopts->nd_useropts = nd_opt;
+ } else {
+ /*
+ * Unknown options must be silently ignored,
+ * to accommodate future extension to the
+ * protocol.
+ */
+ ND_PRINTK2(KERN_NOTICE
+ "%s(): ignored unsupported option; type=%d, len=%d\n",
+ __FUNCTION__,
+ nd_opt->nd_opt_type, nd_opt->nd_opt_len);
+ }
}
opt_len -= l;
nd_opt = ((void *)nd_opt) + l;
@@ -984,6 +1013,53 @@ out:
in6_dev_put(idev);
}
+static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
+{
+ struct icmp6hdr *icmp6h = (struct icmp6hdr *)skb_transport_header(ra);
+ struct sk_buff *skb;
+ struct nlmsghdr *nlh;
+ struct nduseroptmsg *ndmsg;
+ int err;
+ int base_size = NLMSG_ALIGN(sizeof(struct nduseroptmsg)
+ + (opt->nd_opt_len << 3));
+ size_t msg_size = base_size + nla_total_size(sizeof(struct in6_addr));
+
+ skb = nlmsg_new(msg_size, GFP_ATOMIC);
+ if (skb == NULL) {
+ err = -ENOBUFS;
+ goto errout;
+ }
+
+ nlh = nlmsg_put(skb, 0, 0, RTM_NEWNDUSEROPT, base_size, 0);
+ if (nlh == NULL) {
+ goto nla_put_failure;
+ }
+
+ ndmsg = nlmsg_data(nlh);
+ ndmsg->nduseropt_family = AF_INET6;
+ ndmsg->nduseropt_icmp_type = icmp6h->icmp6_type;
+ ndmsg->nduseropt_icmp_code = icmp6h->icmp6_code;
+ ndmsg->nduseropt_opts_len = opt->nd_opt_len << 3;
+
+ memcpy(ndmsg + 1, opt, opt->nd_opt_len << 3);
+
+ NLA_PUT(skb, NDUSEROPT_SRCADDR, sizeof(struct in6_addr),
+ &ipv6_hdr(ra)->saddr);
+ nlmsg_end(skb, nlh);
+
+ err = rtnl_notify(skb, 0, RTNLGRP_ND_USEROPT, NULL, GFP_ATOMIC);
+ if (err < 0)
+ goto errout;
+
+ return;
+
+nla_put_failure:
+ nlmsg_free(skb);
+ err = -EMSGSIZE;
+errout:
+ rtnl_set_sk_err(RTNLGRP_ND_USEROPT, err);
+}
+
static void ndisc_router_discovery(struct sk_buff *skb)
{
struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb);
@@ -1216,6 +1292,15 @@ skip_defrtr:
}
}
+ if (ndopts.nd_useropts) {
+ struct nd_opt_hdr *opt;
+ for (opt = ndopts.nd_useropts;
+ opt;
+ opt = ndisc_next_useropt(opt, ndopts.nd_useropts_end)) {
+ ndisc_ra_useropt(skb, opt);
+ }
+ }
+
if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) {
ND_PRINTK2(KERN_WARNING
"ICMPv6 RA: invalid RA options");
--
Pierre Ynard
For hire in Quebec City, Canada, during Fall 2007
"Une âme dans un corps, c'est comme un dessin sur une feuille de papier."
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH][IPv6] Export userland ND options through netlink (RDNSS support)
2007-10-05 6:09 [PATCH][IPv6] Export userland ND options through netlink (RDNSS support) Pierre Ynard
@ 2007-10-11 4:22 ` David Miller
2010-12-02 22:59 ` David Woodhouse
1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2007-10-11 4:22 UTC (permalink / raw)
To: linkfanel; +Cc: netdev
From: Pierre Ynard <linkfanel@yahoo.fr>
Date: Fri, 5 Oct 2007 08:09:30 +0200
> As discussed before, this patch provides userland with a way to access
> relevant options in Router Advertisements, after they are processed and
> validated by the kernel. Extra options are processed in a generic way;
> this patch only exports RDNSS options described in RFC5006, but support
> to control which options are exported could be easily added.
>
> A new rtnetlink message type is defined, to transport Neighbor Discovery
> options, along with optional context information. At the moment only
> the address of the router sending an RDNSS option is included, but
> additional attributes may be later defined, if needed by new use cases.
>
> Signed-off-by: Pierre Ynard <linkfanel@yahoo.fr>
This seems to include the changes Yoshifuji requested in your
first submission, so I have applied this.
Thanks.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH][IPv6] Export userland ND options through netlink (RDNSS support)
2007-10-05 6:09 [PATCH][IPv6] Export userland ND options through netlink (RDNSS support) Pierre Ynard
2007-10-11 4:22 ` David Miller
@ 2010-12-02 22:59 ` David Woodhouse
1 sibling, 0 replies; 3+ messages in thread
From: David Woodhouse @ 2010-12-02 22:59 UTC (permalink / raw)
To: Pierre Ynard, yoshfuji; +Cc: netdev
On Fri, 2007-10-05 at 08:09 +0200, Pierre Ynard wrote:
> As discussed before, this patch provides userland with a way to access
> relevant options in Router Advertisements, after they are processed and
> validated by the kernel. Extra options are processed in a generic way;
> this patch only exports RDNSS options described in RFC5006, but support
> to control which options are exported could be easily added.
>
> A new rtnetlink message type is defined, to transport Neighbor Discovery
> options, along with optional context information. At the moment only
> the address of the router sending an RDNSS option is included, but
> additional attributes may be later defined, if needed by new use cases.
RFC5006 §6.1 says:
Note: An RDNSS address MUST be used only as long as both the RA
router lifetime and the RDNSS option lifetime have not expired.
The reason is that the RDNSS may not be currently reachable or may
not provide service to the host's current address (e.g., due to
network ingress filtering [16][17]).
But when this option makes its way to userspace, we don't *know* the RA
router lifetime, or even which interface it came in on. I'm not sure how
we can use this correctly.
This is a start at using it in ConnMan... but unless I'm missing
something, we don't have enough information to do it properly:
http://lists.connman.net/pipermail/connman/2010-December/002781.html
--
David Woodhouse Open Source Technology Centre
David.Woodhouse@intel.com Intel Corporation
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-12-02 23:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-05 6:09 [PATCH][IPv6] Export userland ND options through netlink (RDNSS support) Pierre Ynard
2007-10-11 4:22 ` David Miller
2010-12-02 22:59 ` David Woodhouse
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).