vxlan: introduce vxlan_fdb_parse
authorMike Rapoport <mike.rapoport@ravellosystems.com>
Tue, 25 Jun 2013 13:01:53 +0000 (16:01 +0300)
committerStephen Hemminger <stephen@networkplumber.org>
Tue, 25 Jun 2013 16:31:37 +0000 (09:31 -0700)
which will be reused by vxlan_fdb_delete

Signed-off-by: Mike Rapoport <mike.rapoport@ravellosystems.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
drivers/net/vxlan.c

index 306bd94efa898a11366af65ef83ab38b69008932..ee7cc71e57fd913a8710f65cf604fa2a4621acaa 100644 (file)
@@ -518,58 +518,77 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f)
        call_rcu(&f->rcu, vxlan_fdb_free);
 }
 
-/* Add static entry (via netlink) */
-static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
-                        struct net_device *dev,
-                        const unsigned char *addr, u16 flags)
+static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan,
+                          __be32 *ip, __be16 *port, u32 *vni, u32 *ifindex)
 {
-       struct vxlan_dev *vxlan = netdev_priv(dev);
        struct net *net = dev_net(vxlan->dev);
-       __be32 ip;
-       __be16 port;
-       u32 vni, ifindex;
-       int err;
-
-       if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) {
-               pr_info("RTM_NEWNEIGH with invalid state %#x\n",
-                       ndm->ndm_state);
-               return -EINVAL;
-       }
-
-       if (tb[NDA_DST] == NULL)
-               return -EINVAL;
 
-       if (nla_len(tb[NDA_DST]) != sizeof(__be32))
-               return -EAFNOSUPPORT;
+       if (tb[NDA_DST]) {
+               if (nla_len(tb[NDA_DST]) != sizeof(__be32))
+                       return -EAFNOSUPPORT;
 
-       ip = nla_get_be32(tb[NDA_DST]);
+               *ip = nla_get_be32(tb[NDA_DST]);
+       } else {
+               *ip = htonl(INADDR_ANY);
+       }
 
        if (tb[NDA_PORT]) {
                if (nla_len(tb[NDA_PORT]) != sizeof(__be16))
                        return -EINVAL;
-               port = nla_get_be16(tb[NDA_PORT]);
-       } else
-               port = vxlan->dst_port;
+               *port = nla_get_be16(tb[NDA_PORT]);
+       } else {
+               *port = vxlan->dst_port;
+       }
 
        if (tb[NDA_VNI]) {
                if (nla_len(tb[NDA_VNI]) != sizeof(u32))
                        return -EINVAL;
-               vni = nla_get_u32(tb[NDA_VNI]);
-       } else
-               vni = vxlan->default_dst.remote_vni;
+               *vni = nla_get_u32(tb[NDA_VNI]);
+       } else {
+               *vni = vxlan->default_dst.remote_vni;
+       }
 
        if (tb[NDA_IFINDEX]) {
                struct net_device *tdev;
 
                if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32))
                        return -EINVAL;
-               ifindex = nla_get_u32(tb[NDA_IFINDEX]);
-               tdev = dev_get_by_index(net, ifindex);
+               *ifindex = nla_get_u32(tb[NDA_IFINDEX]);
+               tdev = dev_get_by_index(net, *ifindex);
                if (!tdev)
                        return -EADDRNOTAVAIL;
                dev_put(tdev);
-       } else
-               ifindex = 0;
+       } else {
+               *ifindex = 0;
+       }
+
+       return 0;
+}
+
+/* Add static entry (via netlink) */
+static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
+                        struct net_device *dev,
+                        const unsigned char *addr, u16 flags)
+{
+       struct vxlan_dev *vxlan = netdev_priv(dev);
+       /* struct net *net = dev_net(vxlan->dev); */
+       __be32 ip;
+       __be16 port;
+       u32 vni, ifindex;
+       int err;
+
+       if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) {
+               pr_info("RTM_NEWNEIGH with invalid state %#x\n",
+                       ndm->ndm_state);
+               return -EINVAL;
+       }
+
+       if (tb[NDA_DST] == NULL)
+               return -EINVAL;
+
+       err = vxlan_fdb_parse(tb, vxlan, &ip, &port, &vni, &ifindex);
+       if (err)
+               return err;
 
        spin_lock_bh(&vxlan->hash_lock);
        err = vxlan_fdb_create(vxlan, addr, ip, ndm->ndm_state, flags,