Hi Varka,

only code style issues. I don't test it or check it if this makes sense.

On Thu, Oct 03, 2013 at 11:20:39AM +0530, Varka Bhadram wrote:
> hai to all...
> 
> I am attaching the patches for RFC6775.. Please check it and give me the
> suggestions for improvement. If everything is fine i will submit patches to
> linux-net-next...
> 
Make a proper commit msg.
> Signed-off-by: Varka Bhadram <var...@cdac.in>
> 
> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index 04d31c2..595c060 100644
> --- a/net/ipv6/ndisc.c
Put the off topic messages here. Write it with your favorite $EDITOR
after format-patch.

> +++ b/net/ipv6/ndisc.c
> @@ -11,7 +11,6 @@
>   *      as published by the Free Software Foundation; either version
>   *      2 of the License, or (at your option) any later version.
>   */
> -
Let the newline there.

>  /*
>   *    Changes:
>   *
> @@ -61,6 +60,8 @@
>  #include <net/addrconf.h>
>  #include <net/icmp.h>
> 
> +#include <net/af_ieee802154.h>
> +
>  #include <net/netlink.h>
>  #include <linux/rtnetlink.h>
> 
> @@ -164,6 +165,88 @@ static void ndisc_fill_addr_option(struct sk_buff *skb, 
> int
> type, void *data)
>          memset(opt, 0, space);
>  }
> 
> +static struct neighbour *ndisc_lowpan_options_handle(struct net_device *dev,
> +                        const struct in6_addr *saddr,
> +                        struct aro_option *aro)
> +{
> +    struct neighbour *neigh = NULL;
> +    /*
> +     * update / create cache entry
> +     * for the source address
> +     */
> +    neigh = neigh_lookup(&nd_tbl, saddr, dev);
> +    if (neigh) {
> +        /*
> +         * RFC 6775 : 6.5.1 checking for duplicates
> +         */
> +        if (!memcmp(neigh->ha, aro->eui_64, 8)) {
> +
> +            /*
> +             * if the received ARO is having
> +             * registration lifetime zero
> +             * delete the entry
> +             */
> +
> +            if (aro->reg_lifetime == 0) {
> +                neigh->dead = 1;
> +                neigh->nud_state = NUD_FAILED;
> +                aro->status = 0;
> +            } else {
> +                neigh->parms->reg_lifetime = aro->reg_lifetime;
> +                aro->status = 0;
> +            }
> +        } else
> +            aro->status = 1;
Missing brackets.

if the "if" has brackets the else need brackets too. I think this is
codestyle in linux.

> +    } else {
> +        neigh = neigh_create(&nd_tbl, saddr, dev);
> +        if (neigh) {
> +            neigh_update(neigh, aro->eui_64, NUD_STALE, 0);
> +            neigh->parms->reg_lifetime = aro->reg_lifetime;
> +            aro->status = 0;
> +        } else
Missing brackets

> +            /*RFC6775 : scetion 6.5.3 : NCE is ful*/
> +            aro->status = 2;
> +    }
> +    return neigh;
> +}
> +
> +static struct neighbour *ndisc_lowpan_ns(struct sk_buff *skb,
> +                        struct net_device *dev,
> +                        struct aro_option *aro_opt,
> +                        u8 *lladdr)
> +{
> +    const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
> +    struct neighbour *neigh = NULL;
> +    /*
> +     * RFC6775 : 6.5
> +     * if no SLLAO is included , then any included ARO is ignored
> +     */
> +    if (lladdr == NULL && aro_opt != NULL) {

change to if (!laddr && !aro_opt) like  they check for if (neigh) for
non null in rest of code.

> +        ND_PRINTK(2, warn, "NS packet is not having the SLLAO\n");
> +        return NULL;
> +    }
> +
> +    /* if the NS is having both options
> +     */
> +    if (lladdr != NULL && aro_opt != NULL) {
here too.

> +        neigh = ndisc_lowpan_options_handle(dev, saddr, aro_opt);
> +        if (!neigh) {
> +            ND_PRINTK(2, warn,
> +                        "NS : Error in lowpan option handling\n");
> +            return NULL;
> +        }
> +    }
> +
> +    /* if the NS having only SLLAO option
> +     */
> +    if (lladdr != NULL && aro_opt == NULL) {
here too.

> +        neigh = __neigh_lookup(&nd_tbl, saddr, dev, 1);
> +        if (neigh)
> +            neigh_update(neigh, lladdr, NUD_STALE, 0);
> +    }
> +    return neigh;
> +}
> +
>  static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
>                          struct nd_opt_hdr *end)
>  {
> @@ -234,6 +317,20 @@ struct ndisc_options *ndisc_parse_options(u8 *opt, int
> opt_len,
>                  ndopts->nd_opts_ri = nd_opt;
>              break;
>  #endif
> +        /*RFC6775 options for 6lowpan*/
> +        case ND_OPT_ARO:
> +            if (!ndopts->nd_opts_aro)
> +                ndopts->nd_opts_aro = nd_opt;
> +            break;
> +        case ND_OPT_6CO:
> +            if (!ndopts->nd_opts_6co)
> +                ndopts->nd_opts_6co = nd_opt;
> +            break;
> +        case ND_OPT_ABRO:
> +            if (!ndopts->nd_opts_abro)
> +                ndopts->nd_opts_abro = nd_opt;
> +            break;
> +
remove newline here.

>          default:
>              if (ndisc_is_useropt(nd_opt)) {
>                  ndopts->nd_useropts_end = nd_opt;
> @@ -463,9 +560,11 @@ static void ndisc_send_skb(struct sk_buff *skb,
>  }
> 
>  static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
> -              const struct in6_addr *daddr,
> -              const struct in6_addr *solicited_addr,
> -              bool router, bool solicited, bool override, bool inc_opt)
> +                const struct in6_addr *daddr,
> +                const struct in6_addr *solicited_addr,
> +                bool router, bool solicited,
> +                bool override, bool inc_opt,
> +                struct aro_option *aro)
>  {
>      struct sk_buff *skb;
>      struct in6_addr tmpaddr;
> @@ -492,8 +591,12 @@ static void ndisc_send_na(struct net_device *dev, struct
> neighbour *neigh,
> 
>      if (!dev->addr_len)
>          inc_opt = 0;
> -    if (inc_opt)
> +
> +    if (inc_opt) {
>          optlen += ndisc_opt_addr_space(dev);
> +        if (aro)
> +            optlen += ND_OPT_ARO_SPACE;
> +    }
> 
>      skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
>      if (!skb)
> @@ -510,10 +613,17 @@ static void ndisc_send_na(struct net_device *dev, struct
> neighbour *neigh,
>          .target = *solicited_addr,
>      };
> 
> -    if (inc_opt)
> -        ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR,
> -                       dev->dev_addr);
> -
> +    if (inc_opt) {
> +        if (dev->type == ARPHRD_IEEE802154) {
> +            ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR,
> +                                dev->dev_addr);
> +            memcpy((struct aro_option *)
> +                        skb_put(skb, ND_OPT_ARO_SPACE),
> +                        aro, sizeof(*aro));
> +        } else
Missing brackets.

> +            ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR,
> +                                dev->dev_addr);
> +    }
> 
>      ndisc_send_skb(skb, daddr, src_addr);
>  }
> @@ -530,9 +640,10 @@ static void ndisc_send_unsol_na(struct net_device *dev)
>      read_lock_bh(&idev->lock);
>      list_for_each_entry(ifa, &idev->addr_list, if_list) {
>          ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &ifa->addr,
> -                  /*router=*/ !!idev->cnf.forwarding,
> -                  /*solicited=*/ false, /*override=*/ true,
> -                  /*inc_opt=*/ true);
> +                    /*router=*/ !!idev->cnf.forwarding,
> +                    /*solicited=*/ false,
> +                    /*override=*/ true,
> +                    /*inc_opt=*/ true, NULL);
>      }
>      read_unlock_bh(&idev->lock);
> 
> @@ -703,6 +814,9 @@ static void ndisc_recv_ns(struct sk_buff *skb)
>      int dad = ipv6_addr_any(saddr);
>      bool inc;
>      int is_router = -1;
> +#ifdef CONFIG_IEEE802154_6LOWPAN
> +    struct aro_option *aro = NULL;
> +#endif
> 
>      if (skb->len < sizeof(struct nd_msg)) {
>          ND_PRINTK(2, warn, "NS: packet too short\n");
> @@ -716,9 +830,10 @@ static void ndisc_recv_ns(struct sk_buff *skb)
> 
>      /*
>       * RFC2461 7.1.1:
> -     * DAD has to be destined for solicited node multicast address.
> +     * DAD has to be destined for solicited node multicast address
let the dash here. Makes no sense.
>       */
> -    if (dad && !ipv6_addr_is_solict_mult(daddr)) {
> +    if (dev->type != ARPHRD_IEEE802154 &&
> +                dad && !ipv6_addr_is_solict_mult(daddr)) {
>          ND_PRINTK(2, warn, "NS: bad DAD packet (wrong destination)\n");
>          return;
>      }
> @@ -748,6 +863,32 @@ static void ndisc_recv_ns(struct sk_buff *skb)
>          }
>      }
> 
> +#ifdef CONFIG_IEEE802154_6LOWPAN
> +    if (ndopts.nd_opts_aro) {
maybe you can use IS_ENABLED here?

> +        memcpy(aro, (struct aro_option *)ndopts.nd_opts_aro,
> +                            sizeof(*aro));
> +        if (aro->status != 0 || aro->aro_opt.nd_opt_len != 2) {
> +            ND_PRINTK(2, warn,
> +                    "ARO: invalid status and length must be discard the
> packet\n");
wrong intend. Make a new string const "a" "b" => "ab".

> +            return;
> +        }
> +    }
> +
> +    if (dev->type == ARPHRD_IEEE802154) {
> +        neigh = ndisc_lowpan_ns(skb, dev, aro, lladdr);
> +        if (neigh) {
> +            ndisc_send_na(dev, neigh, daddr, &msg->target,
> +                            idev->cnf.forwarding,
> +                            true, false, true, aro);
> +            return;
> +        } else {
> +            ND_PRINTK(2, warn,
> +                    "NS : error in handling Lowpan packet\n");
> +            return;
> +        }
> +    }
> +#endif
> +
>      inc = ipv6_addr_is_multicast(daddr);
> 
>      ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
> @@ -783,7 +924,6 @@ static void ndisc_recv_ns(struct sk_buff *skb)
>              /* XXX: count this drop? */
>              return;
>          }
> -
remove this.

>          if (ipv6_chk_acast_addr(net, dev, &msg->target) ||
>              (idev->cnf.forwarding &&
>               (net->ipv6.devconf_all->proxy_ndp || idev->cnf.proxy_ndp) &&
> @@ -813,7 +953,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
> 
>      if (dad) {
>          ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &msg->target,
> -                  !!is_router, false, (ifp != NULL), true);
> +                  !!is_router, false, (ifp != NULL), true, NULL);
>          goto out;
>      }
> 
> @@ -834,8 +974,8 @@ static void ndisc_recv_ns(struct sk_buff *skb)
>                   NEIGH_UPDATE_F_OVERRIDE);
>      if (neigh || !dev->header_ops) {
>          ndisc_send_na(dev, neigh, saddr, &msg->target,
> -                  !!is_router,
> -                  true, (ifp != NULL && inc), inc);
> +                !!is_router,
> +                true, (ifp != NULL && inc), inc, NULL);
>          if (neigh)
>              neigh_release(neigh);
>      }
> @@ -1009,6 +1149,128 @@ out:
>      return;
>  }
> 
> +static void ndisc_recv_dar(struct sk_buff *skb)
> +{
> +    struct darc_msg *msg = (struct darc_msg *)skb_transport_header(skb);
> +    const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
> +    const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
> +    const struct in6_addr *reg_addr = &msg->reg_addr;
> +    struct inet6_dev *idev;
> +    struct neighbour *neigh;
> +    struct net_device *dev = skb->dev;
> +
> +    /*Packet is from our interface*/
> +    if (dev->type != ARPHRD_IEEE802154)
> +        return;
> +
> +    /* if skb is too short */
> +    if (skb->len < sizeof(struct darc_msg))
> +        return;
> +
> +    idev = in6_dev_get(skb->dev);
> +    if (!idev) {
> +        ND_PRINTK(1, err, "DAR: can't find in6 device\n");
> +        return;
> +    }
> +
> +    /* dont accept DAR if you are not router mode*/
> +    if (!idev->cnf.forwarding)
> +        return;
> +
> +    /* registered address should not be multicast address : RFC6775 */
> +    if (ipv6_addr_is_multicast(reg_addr)) {
> +        ND_PRINTK(2, warn, "DAR : registered address is multicast\n");
> +        return;
> +    }
> +
> +    /*status in the DAR must be zero */
> +    if (msg->status != 0)
> +        return;
> +
> +    /* update / create cache entry
> +      * for the source address
> +     */
> +    neigh = neigh_lookup(&nd_tbl, saddr, dev);
> +    if (neigh) {
> +        if (!memcmp(neigh->ha, msg->eui_64, 8)) {
> +            /* if the received DAR is having
> +             * registration lifetime zero
> +             * delete the entry
> +             */
> +            if (msg->reg_lifetime == 0) {
> +                neigh->dead = 1;
> +                neigh->nud_state = NUD_FAILED;
> +                msg->status = 0;
> +            } else {
> +                neigh->parms->reg_lifetime = msg->reg_lifetime;
> +                msg->status = 0;
> +            }
> +        } else
> +            msg->status = 1;
> +    } else {
> +        neigh = neigh_create(&nd_tbl, saddr, dev);
> +        if (neigh) {
> +            neigh_update(neigh, msg->eui_64, NUD_STALE, 0);
> +            neigh->parms->reg_lifetime = msg->reg_lifetime;
> +            msg->status = 0;
> +        } else
> +            /* NCE is Full */
> +            msg->status = 2;
> +
> +    ndisc_send_dac(dev, neigh, saddr, daddr, msg);
> +}
> +
> +static void ndisc_recv_dac(struct sk_buff *skb)
> +{
> +    struct inet6_dev *idev;
> +    struct net_device *dev = skb->dev;
> +
> +    idev = in6_dev_get(skb->dev);
> +    if (!idev) {
> +        ND_PRINTK(1, err, "DAC: can't find in6 device\n");
> +        return;
> +    }
> +
> +    /* dont accept DAC if you are in router mode*/
> +    if (idev->cnf.forwarding)
> +        return;
> +
> +    if (dev->type != ARPHRD_IEEE802154)
> +        return;
> +
> +}
> +void ndisc_send_dac(struct net_device *dev, struct neighbour *neigh,
> +                        const struct in6_addr *daddr,
> +                        const struct in6_addr *src_addr,
> +                        struct darc_msg *rmsg)
> +{
> +    struct sk_buff *skb;
> +    struct darc_msg *cmsg;
> +
> +    if (daddr == NULL) {
> +        ND_PRINTK(2, warn, "DAC: Undefined destination address\n");
> +        return;
> +    }
> +
> +    /* allocation of socket buffer */
> +    skb = ndisc_alloc_skb(dev, sizeof(*cmsg));
> +    if (!skb)
> +        return;
> +
> +    cmsg = (struct darc_msg *)skb_put(skb, sizeof(*cmsg));
> +
> +    *cmsg = (struct darc_msg) *rmsg;
> +    *cmsg = (struct darc_msg) {
> +            .icmph = {
> +                .icmp6_type =
> +                    NDISC_DUPLICATE_ADDRESS_CONFIRMATION,
> +            },
> +    };
> +
> +    /*sending the packet */
> +    ndisc_send_skb(skb, daddr, src_addr);
> +}
> +
>  static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
>  {
>      struct icmp6hdr *icmp6h = (struct icmp6hdr *)skb_transport_header(ra);
> @@ -1564,6 +1826,14 @@ int ndisc_rcv(struct sk_buff *skb)
>      case NDISC_REDIRECT:
>          ndisc_redirect_rcv(skb);
>          break;
> +    /*Two more ICMP messages according to RFC6775*/
> +    case NDISC_DUPLICATE_ADDRESS_REQUEST:
> +        ndisc_recv_dar(skb);
> +        break;
> +
remove newline.
> +    case NDISC_DUPLICATE_ADDRESS_CONFIRMATION:
> +        ndisc_recv_dac(skb);
> +        break;
>      }
> 
> diff --git a/include/net/ndisc.h b/include/net/ndisc.h
> index 6fea323..092ac6d 100644
> --- a/include/net/ndisc.h
> +++ b/include/net/ndisc.h
> @@ -12,6 +12,12 @@
>  #define NDISC_REDIRECT            137
> 
>  /*
> + * RFC6775 lowpan ND
> + */
> +
> +#define NDISC_DUPLICATE_ADDRESS_REQUEST        157
> +#define NDISC_DUPLICATE_ADDRESS_CONFIRMATION    158
> +/*
>   * Router type: cross-layer information from link-layer to
>   * IPv6 layer reported by certain link types (e.g., RFC4214).
>   */
> @@ -35,6 +41,10 @@ enum {
>      ND_OPT_ROUTE_INFO = 24,        /* RFC4191 */
>      ND_OPT_RDNSS = 25,        /* RFC5006 */
>      ND_OPT_DNSSL = 31,        /* RFC6106 */
> +    ND_OPT_ARO = 33,                /* RFC6775 */
> +    ND_OPT_6CO = 34,                /* RFC6775 */
> +    ND_OPT_ABRO = 35,                /* RFC6775 */
> +
>      __ND_OPT_MAX
>  };
> 
> @@ -43,6 +53,8 @@ enum {
>  #define ND_REACHABLE_TIME        (30*HZ)
>  #define ND_RETRANS_TIMER        HZ
> 
> +#define ND_OPT_ARO_SPACE 16
> +
>  #include <linux/compiler.h>
>  #include <linux/icmpv6.h>
>  #include <linux/in6.h>
> @@ -85,14 +97,43 @@ struct rd_msg {
>      __u8        opt[0];
>  };
> 
> +/*
> + * RFC6775 Duplicate address registration message
> + */
> +
> +struct darc_msg {
> +    struct icmp6hdr icmph;
> +    __u8 status;
> +    __u8 reserved;
> +    __u16 reg_lifetime;
> +    __u8 eui_64[8];
> +    struct in6_addr reg_addr;
> +};
> +
>  struct nd_opt_hdr {
>      __u8        nd_opt_type;
>      __u8        nd_opt_len;
>  } __packed;
> 
> -/* ND options */
> +struct aro_option {
> +    struct nd_opt_hdr aro_opt;
> +    __u8 status;
> +    __u16 reserved;
> +    __u16 reg_lifetime;
> +    __u8 eui_64[8];
> +};
> +
> +/*
> + * ND options
> + */
> +
>  struct ndisc_options {
>      struct nd_opt_hdr *nd_opt_array[__ND_OPT_ARRAY_MAX];
> +    /* lowpan options header fields RFC6775*/
> +    struct nd_opt_hdr *nd_opts_aro;
> +    struct nd_opt_hdr *nd_opts_6co;
> +    struct nd_opt_hdr *nd_opts_abro;
> +
>  #ifdef CONFIG_IPV6_ROUTE_INFO
>      struct nd_opt_hdr *nd_opts_ri;
>      struct nd_opt_hdr *nd_opts_ri_end;
> @@ -190,7 +231,9 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct
> net_device *dev, cons
>  }
> 
>  extern int            ndisc_init(void);
> +extern int            ndisc_late_init(void);
> 
> +extern void            ndisc_late_cleanup(void);
>  extern void            ndisc_cleanup(void);
> 
>  extern int            ndisc_rcv(struct sk_buff *skb);
> @@ -208,6 +251,16 @@ extern void            ndisc_send_rs(struct net_device
> *dev,
>  extern void            ndisc_send_redirect(struct sk_buff *skb,
>                              const struct in6_addr *target);
> 
> +/*
> + * sending DAC : RFC6775
> + */
> +
> +extern void ndisc_send_dac(struct net_device *dev,
> +                    struct neighbour *neigh,
> +                    const struct in6_addr *daddr,
> +                    const struct in6_addr *src_addr,
> +                    struct darc_msg *rmsg);
> +
> 
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 60533db..742f131 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -797,9 +797,13 @@ static void neigh_periodic_work(struct work_struct *work)
>              if (time_before(n->used, n->confirmed))
>                  n->used = n->confirmed;
> 
> -            if (atomic_read(&n->refcnt) == 1 &&
> +            if ((atomic_read(&n->refcnt) == 1) &&
>                  (state == NUD_FAILED ||
> -                 time_after(jiffies, n->used + n->parms->gc_staletime))) {
> +                time_after(jiffies, n->used + n->parms->gc_staletime) ||
> +                #ifdef CONFIG_IEEE802154_6LOWPAN
here too some kind of IS_ENABLED.

> +                time_after(jiffies, n->used + n->parms->reg_lifetime)
> +                #endif
> +                )) {
>                  *np = n->next;
>                  n->dead = 1;
>                  write_unlock(&n->lock);
> @@ -3055,4 +3059,3 @@ static int __init neigh_init(void)
>  }
> 
> diff --git a/include/net/neighbour.h b/include/net/neighbour.h
> index 7e748ad..7d8e4c8 100644
> --- a/include/net/neighbour.h
> +++ b/include/net/neighbour.h
> @@ -67,6 +67,9 @@ struct neigh_parms {
>      int    proxy_delay;
>      int    proxy_qlen;
>      int    locktime;
> +#ifdef CONFIG_IEEE802154
You use CONFIG_IEEE802154 here and this is the first time. All others
are CONFIG_IEEE802154_6LOWPAN.
> +    __u16 reg_lifetime;
> +#endif
>  };
> 
>
I missed the patch ending here, please use git send-email. I can't apply
your patches.

How did you test it, then I can test it on my own in some test scenario.

- Alex

------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from 
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60134791&iu=/4140/ostg.clktrk
_______________________________________________
Linux-zigbee-devel mailing list
Linux-zigbee-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel

Reply via email to