Re: [PATCHv3 net-next 08/12] ipv6: introduce neighbour discovery ops

2016-06-15 Thread YOSHIFUJI Hideaki/吉藤英明


Alexander Aring wrote:
> This patch introduces neighbour discovery ops callback structure. The
> idea is to separate the handling for 6LoWPAN into the 6lowpan module.
> 
> These callback offers 6lowpan different handling, such as 802.15.4 short
> address handling or RFC6775 (Neighbor Discovery Optimization for IPv6
> over 6LoWPANs).
> 
> Cc: David S. Miller 
> Cc: Alexey Kuznetsov 
> Cc: James Morris 
> Cc: Hideaki YOSHIFUJI 
> Cc: Patrick McHardy 
> Signed-off-by: Alexander Aring 

Acked-by: YOSHIFUJI Hideaki 

> ---
>  include/linux/netdevice.h |   5 ++
>  include/net/ndisc.h   | 197 
> +-
>  net/ipv6/addrconf.c   |  13 ++-
>  net/ipv6/ndisc.c  | 101 
>  net/ipv6/route.c  |   8 +-
>  5 files changed, 284 insertions(+), 40 deletions(-)
> 
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 36e43bd..890158e 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1456,6 +1456,8 @@ enum netdev_priv_flags {
>   *   @netdev_ops:Includes several pointers to callbacks,
>   *   if one wants to override the ndo_*() functions
>   *   @ethtool_ops:   Management operations
> + *   @ndisc_ops: Includes callbacks for different IPv6 neighbour
> + *   discovery handling. Necessary for e.g. 6LoWPAN.
>   *   @header_ops:Includes callbacks for creating,parsing,caching,etc
>   *   of Layer 2 headers.
>   *
> @@ -1672,6 +1674,9 @@ struct net_device {
>  #ifdef CONFIG_NET_L3_MASTER_DEV
>   const struct l3mdev_ops *l3mdev_ops;
>  #endif
> +#if IS_ENABLED(CONFIG_IPV6)
> + const struct ndisc_ops *ndisc_ops;
> +#endif
>  
>   const struct header_ops *header_ops;
>  
> diff --git a/include/net/ndisc.h b/include/net/ndisc.h
> index c8962ad..a5e2767 100644
> --- a/include/net/ndisc.h
> +++ b/include/net/ndisc.h
> @@ -58,6 +58,7 @@ struct inet6_dev;
>  struct net_device;
>  struct net_proto_family;
>  struct sk_buff;
> +struct prefix_info;
>  
>  extern struct neigh_table nd_tbl;
>  
> @@ -110,9 +111,182 @@ struct ndisc_options {
>  
>  #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
>  
> -struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
> +struct ndisc_options *ndisc_parse_options(const struct net_device *dev,
> +   u8 *opt, int opt_len,
> struct ndisc_options *ndopts);
>  
> +#define NDISC_OPS_REDIRECT_DATA_SPACE2
> +
> +/*
> + * This structure defines the hooks for IPv6 neighbour discovery.
> + * The following hooks can be defined; unless noted otherwise, they are
> + * optional and can be filled with a null pointer.
> + *
> + * int (*is_useropt)(u8 nd_opt_type):
> + * This function is called when IPv6 decide RA userspace options. if
> + * this function returns 1 then the option given by nd_opt_type will
> + * be handled as userspace option additional to the IPv6 options.
> + *
> + * int (*parse_options)(const struct net_device *dev,
> + *   struct nd_opt_hdr *nd_opt,
> + *   struct ndisc_options *ndopts):
> + * This function is called while parsing ndisc ops and put each position
> + * as pointer into ndopts. If this function return unequal 0, then this
> + * function took care about the ndisc option, if 0 then the IPv6 ndisc
> + * option parser will take care about that option.
> + *
> + * void (*update)(const struct net_device *dev, struct neighbour *n,
> + * u32 flags, u8 icmp6_type,
> + * const struct ndisc_options *ndopts):
> + * This function is called when IPv6 ndisc updates the neighbour cache
> + * entry. Additional options which can be updated may be previously
> + * parsed by parse_opts callback and accessible over ndopts parameter.
> + *
> + * int (*opt_addr_space)(const struct net_device *dev, u8 icmp6_type,
> + *struct neighbour *neigh, u8 *ha_buf,
> + *u8 **ha):
> + * This function is called when the necessary option space will be
> + * calculated before allocating a skb. The parameters neigh, ha_buf
> + * abd ha are available on NDISC_REDIRECT messages only.
> + *
> + * void (*fill_addr_option)(const struct net_device *dev,
> + *   struct sk_buff *skb, u8 icmp6_type,
> + *   const u8 *ha):
> + * This function is called when the skb will finally fill the option
> + * fields inside skb. NOTE: this callback should fill the option
> + * fields to the skb which are previously indicated by opt_space
> + * parameter. That means the decision to add such option should
> + * not lost between these two callbacks, e.g. protected by interface
> + * up state.
> + *
> + * void (*prefix_rcv_add_addr)(struct net *net, struct net_device *dev,
> + *  const struct prefix_info *pinfo,
> + *  

[PATCHv3 net-next 08/12] ipv6: introduce neighbour discovery ops

2016-06-14 Thread Alexander Aring
This patch introduces neighbour discovery ops callback structure. The
idea is to separate the handling for 6LoWPAN into the 6lowpan module.

These callback offers 6lowpan different handling, such as 802.15.4 short
address handling or RFC6775 (Neighbor Discovery Optimization for IPv6
over 6LoWPANs).

Cc: David S. Miller 
Cc: Alexey Kuznetsov 
Cc: James Morris 
Cc: Hideaki YOSHIFUJI 
Cc: Patrick McHardy 
Signed-off-by: Alexander Aring 
---
 include/linux/netdevice.h |   5 ++
 include/net/ndisc.h   | 197 +-
 net/ipv6/addrconf.c   |  13 ++-
 net/ipv6/ndisc.c  | 101 
 net/ipv6/route.c  |   8 +-
 5 files changed, 284 insertions(+), 40 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 36e43bd..890158e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1456,6 +1456,8 @@ enum netdev_priv_flags {
  * @netdev_ops:Includes several pointers to callbacks,
  * if one wants to override the ndo_*() functions
  * @ethtool_ops:   Management operations
+ * @ndisc_ops: Includes callbacks for different IPv6 neighbour
+ * discovery handling. Necessary for e.g. 6LoWPAN.
  * @header_ops:Includes callbacks for creating,parsing,caching,etc
  * of Layer 2 headers.
  *
@@ -1672,6 +1674,9 @@ struct net_device {
 #ifdef CONFIG_NET_L3_MASTER_DEV
const struct l3mdev_ops *l3mdev_ops;
 #endif
+#if IS_ENABLED(CONFIG_IPV6)
+   const struct ndisc_ops *ndisc_ops;
+#endif
 
const struct header_ops *header_ops;
 
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index c8962ad..a5e2767 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -58,6 +58,7 @@ struct inet6_dev;
 struct net_device;
 struct net_proto_family;
 struct sk_buff;
+struct prefix_info;
 
 extern struct neigh_table nd_tbl;
 
@@ -110,9 +111,182 @@ struct ndisc_options {
 
 #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
 
-struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
+struct ndisc_options *ndisc_parse_options(const struct net_device *dev,
+ u8 *opt, int opt_len,
  struct ndisc_options *ndopts);
 
+#define NDISC_OPS_REDIRECT_DATA_SPACE  2
+
+/*
+ * This structure defines the hooks for IPv6 neighbour discovery.
+ * The following hooks can be defined; unless noted otherwise, they are
+ * optional and can be filled with a null pointer.
+ *
+ * int (*is_useropt)(u8 nd_opt_type):
+ * This function is called when IPv6 decide RA userspace options. if
+ * this function returns 1 then the option given by nd_opt_type will
+ * be handled as userspace option additional to the IPv6 options.
+ *
+ * int (*parse_options)(const struct net_device *dev,
+ * struct nd_opt_hdr *nd_opt,
+ * struct ndisc_options *ndopts):
+ * This function is called while parsing ndisc ops and put each position
+ * as pointer into ndopts. If this function return unequal 0, then this
+ * function took care about the ndisc option, if 0 then the IPv6 ndisc
+ * option parser will take care about that option.
+ *
+ * void (*update)(const struct net_device *dev, struct neighbour *n,
+ *   u32 flags, u8 icmp6_type,
+ *   const struct ndisc_options *ndopts):
+ * This function is called when IPv6 ndisc updates the neighbour cache
+ * entry. Additional options which can be updated may be previously
+ * parsed by parse_opts callback and accessible over ndopts parameter.
+ *
+ * int (*opt_addr_space)(const struct net_device *dev, u8 icmp6_type,
+ *  struct neighbour *neigh, u8 *ha_buf,
+ *  u8 **ha):
+ * This function is called when the necessary option space will be
+ * calculated before allocating a skb. The parameters neigh, ha_buf
+ * abd ha are available on NDISC_REDIRECT messages only.
+ *
+ * void (*fill_addr_option)(const struct net_device *dev,
+ * struct sk_buff *skb, u8 icmp6_type,
+ * const u8 *ha):
+ * This function is called when the skb will finally fill the option
+ * fields inside skb. NOTE: this callback should fill the option
+ * fields to the skb which are previously indicated by opt_space
+ * parameter. That means the decision to add such option should
+ * not lost between these two callbacks, e.g. protected by interface
+ * up state.
+ *
+ * void (*prefix_rcv_add_addr)(struct net *net, struct net_device *dev,
+ *const struct prefix_info *pinfo,
+ *struct inet6_dev *in6_dev,
+ *struct in6_addr *addr,
+ *int addr_type, u32 addr_flags,
+ *bool sllao, bool tokenized,
+ *