All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 net-next 0/6] net: ILA notification mechanism and fixes
@ 2017-12-15 18:27 Tom Herbert
  2017-12-15 18:27 ` [PATCH v4 net-next 1/6] lwt: Add net to build_state argument Tom Herbert
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Tom Herbert @ 2017-12-15 18:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, roopa, rohit, Tom Herbert

This patch set adds support to get netlink notifications for ILA 
routes when a route is used. This is done to support ILA forwarding
cache address resolution as well as ILA router redirect mechanisms.

This patch set contains:

- The ILA route notification mechanism
- Routing messages are used over netlink to indicate resolution
  requests
- Add net to ila build_state
- Add flush command to ila_xlat
- Fix use of rhashtable for latest fixes

v4:
 - Remove front end cache per davem feedback
 - Eliminate separate LWT type just use ILA LWT already in place

v3:
 - Removed rhashtable changes to their own patch set
 - Restructure ILA code to be more amenable to changes
 - Remove extra call back functions in resolution interface

Changes from initial RFC:

 - Added net argument to LWT build_state
 - Made resolve timeout an attribute of the LWT encap route
 - Changed ILA notifications to be regular routing messages of event
   RTM_ADDR_RESOLVE, family RTNL_FAMILY_ILA, and group
   RTNLGRP_ILA_NOTIFY


Tom Herbert (6):
  lwt: Add net to build_state argument
  ila: Fix use of rhashtable walk in ila_xlat.c
  ila: Call library function alloc_bucket_locks
  ila: create main ila source file
  ila: Flush netlink command to clear xlat table
  ila: Route notify

 include/net/lwtunnel.h         |   6 +-
 include/uapi/linux/ila.h       |   3 +
 include/uapi/linux/rtnetlink.h |   8 +-
 net/core/lwt_bpf.c             |   2 +-
 net/core/lwtunnel.c            |   4 +-
 net/ipv4/fib_semantics.c       |  13 +-
 net/ipv4/ip_tunnel_core.c      |   4 +-
 net/ipv6/ila/Makefile          |   2 +-
 net/ipv6/ila/ila.h             |  27 +++-
 net/ipv6/ila/ila_common.c      |  30 -----
 net/ipv6/ila/ila_lwt.c         | 270 ++++++++++++++++++++++++++------------
 net/ipv6/ila/ila_main.c        | 121 +++++++++++++++++
 net/ipv6/ila/ila_xlat.c        | 290 ++++++++++++++++++++---------------------
 net/ipv6/route.c               |   2 +-
 net/ipv6/seg6_iptunnel.c       |   2 +-
 net/ipv6/seg6_local.c          |   5 +-
 net/mpls/mpls_iptunnel.c       |   2 +-
 17 files changed, 508 insertions(+), 283 deletions(-)
 create mode 100644 net/ipv6/ila/ila_main.c

-- 
2.11.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v4 net-next 1/6] lwt: Add net to build_state argument
  2017-12-15 18:27 [PATCH v4 net-next 0/6] net: ILA notification mechanism and fixes Tom Herbert
@ 2017-12-15 18:27 ` Tom Herbert
  2017-12-19 15:47   ` Roopa Prabhu
  2017-12-15 18:27 ` [PATCH v4 net-next 2/6] ila: Fix use of rhashtable walk in ila_xlat.c Tom Herbert
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Tom Herbert @ 2017-12-15 18:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, roopa, rohit, Tom Herbert

Users of LWT need to know net if they want to have per net operations
in LWT.

Signed-off-by: Tom Herbert <tom@quantonium.net>
---
 include/net/lwtunnel.h    |  6 +++---
 net/core/lwt_bpf.c        |  2 +-
 net/core/lwtunnel.c       |  4 ++--
 net/ipv4/fib_semantics.c  | 13 ++++++++-----
 net/ipv4/ip_tunnel_core.c |  4 ++--
 net/ipv6/ila/ila_lwt.c    |  2 +-
 net/ipv6/route.c          |  2 +-
 net/ipv6/seg6_iptunnel.c  |  2 +-
 net/ipv6/seg6_local.c     |  5 +++--
 net/mpls/mpls_iptunnel.c  |  2 +-
 10 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/include/net/lwtunnel.h b/include/net/lwtunnel.h
index d747ef975cd8..da5e51e0d122 100644
--- a/include/net/lwtunnel.h
+++ b/include/net/lwtunnel.h
@@ -34,7 +34,7 @@ struct lwtunnel_state {
 };
 
 struct lwtunnel_encap_ops {
-	int (*build_state)(struct nlattr *encap,
+	int (*build_state)(struct net *net, struct nlattr *encap,
 			   unsigned int family, const void *cfg,
 			   struct lwtunnel_state **ts,
 			   struct netlink_ext_ack *extack);
@@ -113,7 +113,7 @@ int lwtunnel_valid_encap_type(u16 encap_type,
 			      struct netlink_ext_ack *extack);
 int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
 				   struct netlink_ext_ack *extack);
-int lwtunnel_build_state(u16 encap_type,
+int lwtunnel_build_state(struct net *net, u16 encap_type,
 			 struct nlattr *encap,
 			 unsigned int family, const void *cfg,
 			 struct lwtunnel_state **lws,
@@ -192,7 +192,7 @@ static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
 	return 0;
 }
 
-static inline int lwtunnel_build_state(u16 encap_type,
+static inline int lwtunnel_build_state(struct net *net, u16 encap_type,
 				       struct nlattr *encap,
 				       unsigned int family, const void *cfg,
 				       struct lwtunnel_state **lws,
diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c
index e7e626fb87bb..3a3ac13fcf06 100644
--- a/net/core/lwt_bpf.c
+++ b/net/core/lwt_bpf.c
@@ -238,7 +238,7 @@ static const struct nla_policy bpf_nl_policy[LWT_BPF_MAX + 1] = {
 	[LWT_BPF_XMIT_HEADROOM]	= { .type = NLA_U32 },
 };
 
-static int bpf_build_state(struct nlattr *nla,
+static int bpf_build_state(struct net *net, struct nlattr *nla,
 			   unsigned int family, const void *cfg,
 			   struct lwtunnel_state **ts,
 			   struct netlink_ext_ack *extack)
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c
index 0b171756453c..b3f2f77dfe72 100644
--- a/net/core/lwtunnel.c
+++ b/net/core/lwtunnel.c
@@ -103,7 +103,7 @@ int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *ops,
 }
 EXPORT_SYMBOL_GPL(lwtunnel_encap_del_ops);
 
-int lwtunnel_build_state(u16 encap_type,
+int lwtunnel_build_state(struct net *net, u16 encap_type,
 			 struct nlattr *encap, unsigned int family,
 			 const void *cfg, struct lwtunnel_state **lws,
 			 struct netlink_ext_ack *extack)
@@ -124,7 +124,7 @@ int lwtunnel_build_state(u16 encap_type,
 	ops = rcu_dereference(lwtun_encaps[encap_type]);
 	if (likely(ops && ops->build_state && try_module_get(ops->owner))) {
 		found = true;
-		ret = ops->build_state(encap, family, cfg, lws, extack);
+		ret = ops->build_state(net, encap, family, cfg, lws, extack);
 		if (ret)
 			module_put(ops->owner);
 	}
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index f04d944f8abe..4979e5c6b9b8 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -523,6 +523,7 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
 			if (nla) {
 				struct lwtunnel_state *lwtstate;
 				struct nlattr *nla_entype;
+				struct net *net = cfg->fc_nlinfo.nl_net;
 
 				nla_entype = nla_find(attrs, attrlen,
 						      RTA_ENCAP_TYPE);
@@ -533,7 +534,7 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
 					goto err_inval;
 				}
 
-				ret = lwtunnel_build_state(nla_get_u16(
+				ret = lwtunnel_build_state(net, nla_get_u16(
 							   nla_entype),
 							   nla,  AF_INET, cfg,
 							   &lwtstate, extack);
@@ -607,7 +608,7 @@ static void fib_rebalance(struct fib_info *fi)
 
 #endif /* CONFIG_IP_ROUTE_MULTIPATH */
 
-static int fib_encap_match(u16 encap_type,
+static int fib_encap_match(struct net *net, u16 encap_type,
 			   struct nlattr *encap,
 			   const struct fib_nh *nh,
 			   const struct fib_config *cfg,
@@ -619,7 +620,7 @@ static int fib_encap_match(u16 encap_type,
 	if (encap_type == LWTUNNEL_ENCAP_NONE)
 		return 0;
 
-	ret = lwtunnel_build_state(encap_type, encap, AF_INET,
+	ret = lwtunnel_build_state(net, encap_type, encap, AF_INET,
 				   cfg, &lwtstate, extack);
 	if (!ret) {
 		result = lwtunnel_cmp_encap(lwtstate, nh->nh_lwtstate);
@@ -632,6 +633,7 @@ static int fib_encap_match(u16 encap_type,
 int fib_nh_match(struct fib_config *cfg, struct fib_info *fi,
 		 struct netlink_ext_ack *extack)
 {
+	struct net *net = cfg->fc_nlinfo.nl_net;
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 	struct rtnexthop *rtnh;
 	int remaining;
@@ -642,7 +644,8 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi,
 
 	if (cfg->fc_oif || cfg->fc_gw) {
 		if (cfg->fc_encap) {
-			if (fib_encap_match(cfg->fc_encap_type, cfg->fc_encap,
+			if (fib_encap_match(net, cfg->fc_encap_type,
+					    cfg->fc_encap,
 					    fi->fib_nh, cfg, extack))
 				return 1;
 		}
@@ -1180,7 +1183,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg,
 					       "LWT encap type not specified");
 				goto err_inval;
 			}
-			err = lwtunnel_build_state(cfg->fc_encap_type,
+			err = lwtunnel_build_state(net, cfg->fc_encap_type,
 						   cfg->fc_encap, AF_INET, cfg,
 						   &lwtstate, extack);
 			if (err)
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index 2f39479be92f..32e05aa6117d 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -228,7 +228,7 @@ static const struct nla_policy ip_tun_policy[LWTUNNEL_IP_MAX + 1] = {
 	[LWTUNNEL_IP_FLAGS]	= { .type = NLA_U16 },
 };
 
-static int ip_tun_build_state(struct nlattr *attr,
+static int ip_tun_build_state(struct net *net, struct nlattr *attr,
 			      unsigned int family, const void *cfg,
 			      struct lwtunnel_state **ts,
 			      struct netlink_ext_ack *extack)
@@ -327,7 +327,7 @@ static const struct nla_policy ip6_tun_policy[LWTUNNEL_IP6_MAX + 1] = {
 	[LWTUNNEL_IP6_FLAGS]		= { .type = NLA_U16 },
 };
 
-static int ip6_tun_build_state(struct nlattr *attr,
+static int ip6_tun_build_state(struct net *net, struct nlattr *attr,
 			       unsigned int family, const void *cfg,
 			       struct lwtunnel_state **ts,
 			       struct netlink_ext_ack *extack)
diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c
index 3d56a2fb6f86..9f1e46a1468e 100644
--- a/net/ipv6/ila/ila_lwt.c
+++ b/net/ipv6/ila/ila_lwt.c
@@ -125,7 +125,7 @@ static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
 	[ILA_ATTR_HOOK_TYPE] = { .type = NLA_U8, },
 };
 
-static int ila_build_state(struct nlattr *nla,
+static int ila_build_state(struct net *net, struct nlattr *nla,
 			   unsigned int family, const void *cfg,
 			   struct lwtunnel_state **ts,
 			   struct netlink_ext_ack *extack)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b3f4d19b3ca5..0e0cc97e8f42 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2565,7 +2565,7 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
 	if (cfg->fc_encap) {
 		struct lwtunnel_state *lwtstate;
 
-		err = lwtunnel_build_state(cfg->fc_encap_type,
+		err = lwtunnel_build_state(net, cfg->fc_encap_type,
 					   cfg->fc_encap, AF_INET6, cfg,
 					   &lwtstate, extack);
 		if (err)
diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
index bd6cc688bd19..a6cf2fba15f3 100644
--- a/net/ipv6/seg6_iptunnel.c
+++ b/net/ipv6/seg6_iptunnel.c
@@ -359,7 +359,7 @@ static int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 	return err;
 }
 
-static int seg6_build_state(struct nlattr *nla,
+static int seg6_build_state(struct net *net, struct nlattr *nla,
 			    unsigned int family, const void *cfg,
 			    struct lwtunnel_state **ts,
 			    struct netlink_ext_ack *extack)
diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index 825b8e01f947..45dc670c5a93 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -779,8 +779,9 @@ static int parse_nla_action(struct nlattr **attrs, struct seg6_local_lwt *slwt)
 	return 0;
 }
 
-static int seg6_local_build_state(struct nlattr *nla, unsigned int family,
-				  const void *cfg, struct lwtunnel_state **ts,
+static int seg6_local_build_state(struct net *net, struct nlattr *nla,
+				  unsigned int family, const void *cfg,
+				  struct lwtunnel_state **ts,
 				  struct netlink_ext_ack *extack)
 {
 	struct nlattr *tb[SEG6_LOCAL_MAX + 1];
diff --git a/net/mpls/mpls_iptunnel.c b/net/mpls/mpls_iptunnel.c
index 6e558a419f60..c947310cc04f 100644
--- a/net/mpls/mpls_iptunnel.c
+++ b/net/mpls/mpls_iptunnel.c
@@ -157,7 +157,7 @@ static int mpls_xmit(struct sk_buff *skb)
 	return -EINVAL;
 }
 
-static int mpls_build_state(struct nlattr *nla,
+static int mpls_build_state(struct net *net, struct nlattr *nla,
 			    unsigned int family, const void *cfg,
 			    struct lwtunnel_state **ts,
 			    struct netlink_ext_ack *extack)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v4 net-next 2/6] ila: Fix use of rhashtable walk in ila_xlat.c
  2017-12-15 18:27 [PATCH v4 net-next 0/6] net: ILA notification mechanism and fixes Tom Herbert
  2017-12-15 18:27 ` [PATCH v4 net-next 1/6] lwt: Add net to build_state argument Tom Herbert
@ 2017-12-15 18:27 ` Tom Herbert
  2017-12-15 18:27 ` [PATCH v4 net-next 3/6] ila: Call library function alloc_bucket_locks Tom Herbert
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Tom Herbert @ 2017-12-15 18:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, roopa, rohit, Tom Herbert

Perform better EAGAIN handling, handle case where ila_dump_info
fails and we missed objects in the dump, and add a skip index
to skip over ila entires in a list on a rhashtable node that have
already been visited (by a previous call to ila_nl_dump).

Signed-off-by: Tom Herbert <tom@quantonium.net>
---
 net/ipv6/ila/ila_xlat.c | 70 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 54 insertions(+), 16 deletions(-)

diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c
index 44c39c5f0638..887dd5b785b5 100644
--- a/net/ipv6/ila/ila_xlat.c
+++ b/net/ipv6/ila/ila_xlat.c
@@ -474,24 +474,31 @@ static int ila_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info)
 
 struct ila_dump_iter {
 	struct rhashtable_iter rhiter;
+	int skip;
 };
 
 static int ila_nl_dump_start(struct netlink_callback *cb)
 {
 	struct net *net = sock_net(cb->skb->sk);
 	struct ila_net *ilan = net_generic(net, ila_net_id);
-	struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args[0];
+	struct ila_dump_iter *iter;
+	int ret;
 
-	if (!iter) {
-		iter = kmalloc(sizeof(*iter), GFP_KERNEL);
-		if (!iter)
-			return -ENOMEM;
+	iter = kmalloc(sizeof(*iter), GFP_KERNEL);
+	if (!iter)
+		return -ENOMEM;
 
-		cb->args[0] = (long)iter;
+	ret = rhashtable_walk_init(&ilan->rhash_table, &iter->rhiter,
+				   GFP_KERNEL);
+	if (ret) {
+		kfree(iter);
+		return ret;
 	}
 
-	return rhashtable_walk_init(&ilan->rhash_table, &iter->rhiter,
-				    GFP_KERNEL);
+	iter->skip = 0;
+	cb->args[0] = (long)iter;
+
+	return ret;
 }
 
 static int ila_nl_dump_done(struct netlink_callback *cb)
@@ -509,20 +516,45 @@ static int ila_nl_dump(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args[0];
 	struct rhashtable_iter *rhiter = &iter->rhiter;
+	int skip = iter->skip;
 	struct ila_map *ila;
 	int ret;
 
 	rhashtable_walk_start(rhiter);
 
-	for (;;) {
-		ila = rhashtable_walk_next(rhiter);
+	/* Get first entry */
+	ila = rhashtable_walk_peek(rhiter);
+
+	if (ila && !IS_ERR(ila) && skip) {
+		/* Skip over visited entries */
+
+		while (ila && skip) {
+			/* Skip over any ila entries in this list that we
+			 * have already dumped.
+			 */
+			ila = rcu_access_pointer(ila->next);
+			skip--;
+		}
+	}
 
+	skip = 0;
+
+	for (;;) {
 		if (IS_ERR(ila)) {
-			if (PTR_ERR(ila) == -EAGAIN)
-				continue;
 			ret = PTR_ERR(ila);
-			goto done;
+			if (ret == -EAGAIN) {
+				/* Table has changed and iter has reset. Return
+				 * -EAGAIN to the application even if we have
+				 * written data to the skb. The application
+				 * needs to deal with this.
+				 */
+
+				goto out_ret;
+			} else {
+				break;
+			}
 		} else if (!ila) {
+			ret = 0;
 			break;
 		}
 
@@ -531,15 +563,21 @@ static int ila_nl_dump(struct sk_buff *skb, struct netlink_callback *cb)
 					     cb->nlh->nlmsg_seq, NLM_F_MULTI,
 					     skb, ILA_CMD_GET);
 			if (ret)
-				goto done;
+				goto out;
 
+			skip++;
 			ila = rcu_access_pointer(ila->next);
 		}
+
+		skip = 0;
+		ila = rhashtable_walk_next(rhiter);
 	}
 
-	ret = skb->len;
+out:
+	iter->skip = skip;
+	ret = (skb->len ? : ret);
 
-done:
+out_ret:
 	rhashtable_walk_stop(rhiter);
 	return ret;
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v4 net-next 3/6] ila: Call library function alloc_bucket_locks
  2017-12-15 18:27 [PATCH v4 net-next 0/6] net: ILA notification mechanism and fixes Tom Herbert
  2017-12-15 18:27 ` [PATCH v4 net-next 1/6] lwt: Add net to build_state argument Tom Herbert
  2017-12-15 18:27 ` [PATCH v4 net-next 2/6] ila: Fix use of rhashtable walk in ila_xlat.c Tom Herbert
@ 2017-12-15 18:27 ` Tom Herbert
  2017-12-16 20:47   ` kbuild test robot
  2017-12-15 18:27 ` [PATCH v4 net-next 4/6] ila: create main ila source file Tom Herbert
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Tom Herbert @ 2017-12-15 18:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, roopa, rohit, Tom Herbert

To allocate the array of bucket locks for the hash table we now
call library function alloc_bucket_spinlocks.

Signed-off-by: Tom Herbert <tom@quantonium.net>
---
 net/ipv6/ila/ila_xlat.c | 22 +++++-----------------
 1 file changed, 5 insertions(+), 17 deletions(-)

diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c
index 887dd5b785b5..3ef8869ac508 100644
--- a/net/ipv6/ila/ila_xlat.c
+++ b/net/ipv6/ila/ila_xlat.c
@@ -31,26 +31,14 @@ struct ila_net {
 	bool hooks_registered;
 };
 
+#define MAX_LOCKS 1024
 #define	LOCKS_PER_CPU 10
 
 static int alloc_ila_locks(struct ila_net *ilan)
 {
-	unsigned int i, size;
-	unsigned int nr_pcpus = num_possible_cpus();
-
-	nr_pcpus = min_t(unsigned int, nr_pcpus, 32UL);
-	size = roundup_pow_of_two(nr_pcpus * LOCKS_PER_CPU);
-
-	if (sizeof(spinlock_t) != 0) {
-		ilan->locks = kvmalloc(size * sizeof(spinlock_t), GFP_KERNEL);
-		if (!ilan->locks)
-			return -ENOMEM;
-		for (i = 0; i < size; i++)
-			spin_lock_init(&ilan->locks[i]);
-	}
-	ilan->locks_mask = size - 1;
-
-	return 0;
+	return alloc_bucket_spinlocks(&ilan->xlat.locks, &ilan->xlat.locks_mask,
+				      MAX_LOCKS, LOCKS_PER_CPU,
+				      GFP_KERNEL);
 }
 
 static u32 hashrnd __read_mostly;
@@ -639,7 +627,7 @@ static __net_exit void ila_exit_net(struct net *net)
 
 	rhashtable_free_and_destroy(&ilan->rhash_table, ila_free_cb, NULL);
 
-	kvfree(ilan->locks);
+	free_bucket_spinlocks(ilan->xlat.locks);
 
 	if (ilan->hooks_registered)
 		nf_unregister_net_hooks(net, ila_nf_hook_ops,
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v4 net-next 4/6] ila: create main ila source file
  2017-12-15 18:27 [PATCH v4 net-next 0/6] net: ILA notification mechanism and fixes Tom Herbert
                   ` (2 preceding siblings ...)
  2017-12-15 18:27 ` [PATCH v4 net-next 3/6] ila: Call library function alloc_bucket_locks Tom Herbert
@ 2017-12-15 18:27 ` Tom Herbert
  2017-12-15 18:27 ` [PATCH v4 net-next 5/6] ila: Flush netlink command to clear xlat table Tom Herbert
  2017-12-15 18:28 ` [PATCH v4 net-next 6/6] ila: Route notify Tom Herbert
  5 siblings, 0 replies; 12+ messages in thread
From: Tom Herbert @ 2017-12-15 18:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, roopa, rohit, Tom Herbert

Create a main ila file that contains the module initialization functions
as well as netlink definitions. Previously these were defined in
ila_xlat and ila_common. This approach allows better extensibility.

Signed-off-by: Tom Herbert <tom@quantonium.net>
---
 net/ipv6/ila/Makefile     |   2 +-
 net/ipv6/ila/ila.h        |  26 ++++++++-
 net/ipv6/ila/ila_common.c |  30 ----------
 net/ipv6/ila/ila_main.c   | 115 ++++++++++++++++++++++++++++++++++++++
 net/ipv6/ila/ila_xlat.c   | 138 +++++++++-------------------------------------
 5 files changed, 166 insertions(+), 145 deletions(-)
 create mode 100644 net/ipv6/ila/ila_main.c

diff --git a/net/ipv6/ila/Makefile b/net/ipv6/ila/Makefile
index 4b32e5921e5c..b7739aba6e68 100644
--- a/net/ipv6/ila/Makefile
+++ b/net/ipv6/ila/Makefile
@@ -4,4 +4,4 @@
 
 obj-$(CONFIG_IPV6_ILA) += ila.o
 
-ila-objs := ila_common.o ila_lwt.o ila_xlat.o
+ila-objs := ila_main.o ila_common.o ila_lwt.o ila_xlat.o
diff --git a/net/ipv6/ila/ila.h b/net/ipv6/ila/ila.h
index 3c7a11b62334..faba7824ea56 100644
--- a/net/ipv6/ila/ila.h
+++ b/net/ipv6/ila/ila.h
@@ -19,6 +19,7 @@
 #include <linux/skbuff.h>
 #include <linux/types.h>
 #include <net/checksum.h>
+#include <net/genetlink.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <uapi/linux/ila.h>
@@ -104,9 +105,30 @@ void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p,
 
 void ila_init_saved_csum(struct ila_params *p);
 
+struct ila_net {
+	struct {
+		struct rhashtable rhash_table;
+		spinlock_t *locks; /* Bucket locks for entry manipulation */
+		unsigned int locks_mask;
+		bool hooks_registered;
+	} xlat;
+};
+
 int ila_lwt_init(void);
 void ila_lwt_fini(void);
-int ila_xlat_init(void);
-void ila_xlat_fini(void);
+
+int ila_xlat_init_net(struct net *net);
+void ila_xlat_exit_net(struct net *net);
+
+int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info);
+int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info);
+int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info);
+int ila_xlat_nl_dump_start(struct netlink_callback *cb);
+int ila_xlat_nl_dump_done(struct netlink_callback *cb);
+int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb);
+
+extern unsigned int ila_net_id;
+
+extern struct genl_family ila_nl_family;
 
 #endif /* __ILA_H */
diff --git a/net/ipv6/ila/ila_common.c b/net/ipv6/ila/ila_common.c
index 8c88ecf29b93..579310466eac 100644
--- a/net/ipv6/ila/ila_common.c
+++ b/net/ipv6/ila/ila_common.c
@@ -154,33 +154,3 @@ void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p,
 	iaddr->loc = p->locator;
 }
 
-static int __init ila_init(void)
-{
-	int ret;
-
-	ret = ila_lwt_init();
-
-	if (ret)
-		goto fail_lwt;
-
-	ret = ila_xlat_init();
-	if (ret)
-		goto fail_xlat;
-
-	return 0;
-fail_xlat:
-	ila_lwt_fini();
-fail_lwt:
-	return ret;
-}
-
-static void __exit ila_fini(void)
-{
-	ila_xlat_fini();
-	ila_lwt_fini();
-}
-
-module_init(ila_init);
-module_exit(ila_fini);
-MODULE_AUTHOR("Tom Herbert <tom@herbertland.com>");
-MODULE_LICENSE("GPL");
diff --git a/net/ipv6/ila/ila_main.c b/net/ipv6/ila/ila_main.c
new file mode 100644
index 000000000000..f6ac6b14577e
--- /dev/null
+++ b/net/ipv6/ila/ila_main.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <net/genetlink.h>
+#include <net/ila.h>
+#include <net/netns/generic.h>
+#include <uapi/linux/genetlink.h>
+#include "ila.h"
+
+static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
+	[ILA_ATTR_LOCATOR] = { .type = NLA_U64, },
+	[ILA_ATTR_LOCATOR_MATCH] = { .type = NLA_U64, },
+	[ILA_ATTR_IFINDEX] = { .type = NLA_U32, },
+	[ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, },
+	[ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, },
+};
+
+static const struct genl_ops ila_nl_ops[] = {
+	{
+		.cmd = ILA_CMD_ADD,
+		.doit = ila_xlat_nl_cmd_add_mapping,
+		.policy = ila_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = ILA_CMD_DEL,
+		.doit = ila_xlat_nl_cmd_del_mapping,
+		.policy = ila_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = ILA_CMD_GET,
+		.doit = ila_xlat_nl_cmd_get_mapping,
+		.start = ila_xlat_nl_dump_start,
+		.dumpit = ila_xlat_nl_dump,
+		.done = ila_xlat_nl_dump_done,
+		.policy = ila_nl_policy,
+	},
+};
+
+unsigned int ila_net_id;
+
+struct genl_family ila_nl_family __ro_after_init = {
+	.hdrsize	= 0,
+	.name		= ILA_GENL_NAME,
+	.version	= ILA_GENL_VERSION,
+	.maxattr	= ILA_ATTR_MAX,
+	.netnsok	= true,
+	.parallel_ops	= true,
+	.module		= THIS_MODULE,
+	.ops		= ila_nl_ops,
+	.n_ops		= ARRAY_SIZE(ila_nl_ops),
+};
+
+static __net_init int ila_init_net(struct net *net)
+{
+	int err;
+
+	err = ila_xlat_init_net(net);
+	if (err)
+		goto ila_xlat_init_fail;
+
+	return 0;
+
+ila_xlat_init_fail:
+	return err;
+}
+
+static __net_exit void ila_exit_net(struct net *net)
+{
+	ila_xlat_exit_net(net);
+}
+
+static struct pernet_operations ila_net_ops = {
+	.init = ila_init_net,
+	.exit = ila_exit_net,
+	.id   = &ila_net_id,
+	.size = sizeof(struct ila_net),
+};
+
+static int __init ila_init(void)
+{
+	int ret;
+
+	ret = register_pernet_device(&ila_net_ops);
+	if (ret)
+		goto register_device_fail;
+
+	ret = genl_register_family(&ila_nl_family);
+	if (ret)
+		goto register_family_fail;
+
+	ret = ila_lwt_init();
+	if (ret)
+		goto fail_lwt;
+
+	return 0;
+
+fail_lwt:
+	genl_unregister_family(&ila_nl_family);
+register_family_fail:
+	unregister_pernet_device(&ila_net_ops);
+register_device_fail:
+	return ret;
+}
+
+static void __exit ila_fini(void)
+{
+	ila_lwt_fini();
+	genl_unregister_family(&ila_nl_family);
+	unregister_pernet_device(&ila_net_ops);
+}
+
+module_init(ila_init);
+module_exit(ila_fini);
+MODULE_AUTHOR("Tom Herbert <tom@herbertland.com>");
+MODULE_LICENSE("GPL");
diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c
index 3ef8869ac508..d05de891dfb6 100644
--- a/net/ipv6/ila/ila_xlat.c
+++ b/net/ipv6/ila/ila_xlat.c
@@ -22,15 +22,6 @@ struct ila_map {
 	struct rcu_head rcu;
 };
 
-static unsigned int ila_net_id;
-
-struct ila_net {
-	struct rhashtable rhash_table;
-	spinlock_t *locks; /* Bucket locks for entry manipulation */
-	unsigned int locks_mask;
-	bool hooks_registered;
-};
-
 #define MAX_LOCKS 1024
 #define	LOCKS_PER_CPU 10
 
@@ -58,7 +49,7 @@ static inline u32 ila_locator_hash(struct ila_locator loc)
 static inline spinlock_t *ila_get_lock(struct ila_net *ilan,
 				       struct ila_locator loc)
 {
-	return &ilan->locks[ila_locator_hash(loc) & ilan->locks_mask];
+	return &ilan->xlat.locks[ila_locator_hash(loc) & ilan->xlat.locks_mask];
 }
 
 static inline int ila_cmp_wildcards(struct ila_map *ila,
@@ -102,16 +93,6 @@ static const struct rhashtable_params rht_params = {
 	.obj_cmpfn = ila_cmpfn,
 };
 
-static struct genl_family ila_nl_family;
-
-static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
-	[ILA_ATTR_LOCATOR] = { .type = NLA_U64, },
-	[ILA_ATTR_LOCATOR_MATCH] = { .type = NLA_U64, },
-	[ILA_ATTR_IFINDEX] = { .type = NLA_U32, },
-	[ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, },
-	[ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, },
-};
-
 static int parse_nl_config(struct genl_info *info,
 			   struct ila_xlat_params *xp)
 {
@@ -149,7 +130,7 @@ static inline struct ila_map *ila_lookup_wildcards(struct ila_addr *iaddr,
 {
 	struct ila_map *ila;
 
-	ila = rhashtable_lookup_fast(&ilan->rhash_table, &iaddr->loc,
+	ila = rhashtable_lookup_fast(&ilan->xlat.rhash_table, &iaddr->loc,
 				     rht_params);
 	while (ila) {
 		if (!ila_cmp_wildcards(ila, iaddr, ifindex))
@@ -166,7 +147,7 @@ static inline struct ila_map *ila_lookup_by_params(struct ila_xlat_params *xp,
 {
 	struct ila_map *ila;
 
-	ila = rhashtable_lookup_fast(&ilan->rhash_table,
+	ila = rhashtable_lookup_fast(&ilan->xlat.rhash_table,
 				     &xp->ip.locator_match,
 				     rht_params);
 	while (ila) {
@@ -222,7 +203,7 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp)
 	spinlock_t *lock = ila_get_lock(ilan, xp->ip.locator_match);
 	int err = 0, order;
 
-	if (!ilan->hooks_registered) {
+	if (!ilan->xlat.hooks_registered) {
 		/* We defer registering net hooks in the namespace until the
 		 * first mapping is added.
 		 */
@@ -231,7 +212,7 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp)
 		if (err)
 			return err;
 
-		ilan->hooks_registered = true;
+		ilan->xlat.hooks_registered = true;
 	}
 
 	ila = kzalloc(sizeof(*ila), GFP_KERNEL);
@@ -246,12 +227,12 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp)
 
 	spin_lock(lock);
 
-	head = rhashtable_lookup_fast(&ilan->rhash_table,
+	head = rhashtable_lookup_fast(&ilan->xlat.rhash_table,
 				      &xp->ip.locator_match,
 				      rht_params);
 	if (!head) {
 		/* New entry for the rhash_table */
-		err = rhashtable_lookup_insert_fast(&ilan->rhash_table,
+		err = rhashtable_lookup_insert_fast(&ilan->xlat.rhash_table,
 						    &ila->node, rht_params);
 	} else {
 		struct ila_map *tila = head, *prev = NULL;
@@ -277,7 +258,7 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp)
 		} else {
 			/* Make this ila new head */
 			RCU_INIT_POINTER(ila->next, head);
-			err = rhashtable_replace_fast(&ilan->rhash_table,
+			err = rhashtable_replace_fast(&ilan->xlat.rhash_table,
 						      &head->node,
 						      &ila->node, rht_params);
 			if (err)
@@ -303,7 +284,7 @@ static int ila_del_mapping(struct net *net, struct ila_xlat_params *xp)
 
 	spin_lock(lock);
 
-	head = rhashtable_lookup_fast(&ilan->rhash_table,
+	head = rhashtable_lookup_fast(&ilan->xlat.rhash_table,
 				      &xp->ip.locator_match, rht_params);
 	ila = head;
 
@@ -333,15 +314,15 @@ static int ila_del_mapping(struct net *net, struct ila_xlat_params *xp)
 				 * table
 				 */
 				err = rhashtable_replace_fast(
-					&ilan->rhash_table, &ila->node,
+					&ilan->xlat.rhash_table, &ila->node,
 					&head->node, rht_params);
 				if (err)
 					goto out;
 			} else {
 				/* Entry no longer used */
-				err = rhashtable_remove_fast(&ilan->rhash_table,
-							     &ila->node,
-							     rht_params);
+				err = rhashtable_remove_fast(
+						&ilan->xlat.rhash_table,
+						&ila->node, rht_params);
 			}
 		}
 
@@ -356,7 +337,7 @@ static int ila_del_mapping(struct net *net, struct ila_xlat_params *xp)
 	return err;
 }
 
-static int ila_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info)
+int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net *net = genl_info_net(info);
 	struct ila_xlat_params p;
@@ -369,7 +350,7 @@ static int ila_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info)
 	return ila_add_mapping(net, &p);
 }
 
-static int ila_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info)
+int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net *net = genl_info_net(info);
 	struct ila_xlat_params xp;
@@ -421,7 +402,7 @@ static int ila_dump_info(struct ila_map *ila,
 	return -EMSGSIZE;
 }
 
-static int ila_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info)
+int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net *net = genl_info_net(info);
 	struct ila_net *ilan = net_generic(net, ila_net_id);
@@ -465,7 +446,7 @@ struct ila_dump_iter {
 	int skip;
 };
 
-static int ila_nl_dump_start(struct netlink_callback *cb)
+int ila_xlat_nl_dump_start(struct netlink_callback *cb)
 {
 	struct net *net = sock_net(cb->skb->sk);
 	struct ila_net *ilan = net_generic(net, ila_net_id);
@@ -476,7 +457,7 @@ static int ila_nl_dump_start(struct netlink_callback *cb)
 	if (!iter)
 		return -ENOMEM;
 
-	ret = rhashtable_walk_init(&ilan->rhash_table, &iter->rhiter,
+	ret = rhashtable_walk_init(&ilan->xlat.rhash_table, &iter->rhiter,
 				   GFP_KERNEL);
 	if (ret) {
 		kfree(iter);
@@ -489,7 +470,7 @@ static int ila_nl_dump_start(struct netlink_callback *cb)
 	return ret;
 }
 
-static int ila_nl_dump_done(struct netlink_callback *cb)
+int ila_xlat_nl_dump_done(struct netlink_callback *cb)
 {
 	struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args[0];
 
@@ -500,7 +481,7 @@ static int ila_nl_dump_done(struct netlink_callback *cb)
 	return 0;
 }
 
-static int ila_nl_dump(struct sk_buff *skb, struct netlink_callback *cb)
+int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	struct ila_dump_iter *iter = (struct ila_dump_iter *)cb->args[0];
 	struct rhashtable_iter *rhiter = &iter->rhiter;
@@ -570,77 +551,35 @@ static int ila_nl_dump(struct sk_buff *skb, struct netlink_callback *cb)
 	return ret;
 }
 
-static const struct genl_ops ila_nl_ops[] = {
-	{
-		.cmd = ILA_CMD_ADD,
-		.doit = ila_nl_cmd_add_mapping,
-		.policy = ila_nl_policy,
-		.flags = GENL_ADMIN_PERM,
-	},
-	{
-		.cmd = ILA_CMD_DEL,
-		.doit = ila_nl_cmd_del_mapping,
-		.policy = ila_nl_policy,
-		.flags = GENL_ADMIN_PERM,
-	},
-	{
-		.cmd = ILA_CMD_GET,
-		.doit = ila_nl_cmd_get_mapping,
-		.start = ila_nl_dump_start,
-		.dumpit = ila_nl_dump,
-		.done = ila_nl_dump_done,
-		.policy = ila_nl_policy,
-	},
-};
-
-static struct genl_family ila_nl_family __ro_after_init = {
-	.hdrsize	= 0,
-	.name		= ILA_GENL_NAME,
-	.version	= ILA_GENL_VERSION,
-	.maxattr	= ILA_ATTR_MAX,
-	.netnsok	= true,
-	.parallel_ops	= true,
-	.module		= THIS_MODULE,
-	.ops		= ila_nl_ops,
-	.n_ops		= ARRAY_SIZE(ila_nl_ops),
-};
-
 #define ILA_HASH_TABLE_SIZE 1024
 
-static __net_init int ila_init_net(struct net *net)
+int ila_xlat_init_net(struct net *net)
 {
-	int err;
 	struct ila_net *ilan = net_generic(net, ila_net_id);
+	int err;
 
 	err = alloc_ila_locks(ilan);
 	if (err)
 		return err;
 
-	rhashtable_init(&ilan->rhash_table, &rht_params);
+	rhashtable_init(&ilan->xlat.rhash_table, &rht_params);
 
 	return 0;
 }
 
-static __net_exit void ila_exit_net(struct net *net)
+void ila_xlat_exit_net(struct net *net)
 {
 	struct ila_net *ilan = net_generic(net, ila_net_id);
 
-	rhashtable_free_and_destroy(&ilan->rhash_table, ila_free_cb, NULL);
+	rhashtable_free_and_destroy(&ilan->xlat.rhash_table, ila_free_cb, NULL);
 
 	free_bucket_spinlocks(ilan->xlat.locks);
 
-	if (ilan->hooks_registered)
+	if (ilan->xlat.hooks_registered)
 		nf_unregister_net_hooks(net, ila_nf_hook_ops,
 					ARRAY_SIZE(ila_nf_hook_ops));
 }
 
-static struct pernet_operations ila_net_ops = {
-	.init = ila_init_net,
-	.exit = ila_exit_net,
-	.id   = &ila_net_id,
-	.size = sizeof(struct ila_net),
-};
-
 static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila)
 {
 	struct ila_map *ila;
@@ -667,28 +606,3 @@ static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila)
 	return 0;
 }
 
-int __init ila_xlat_init(void)
-{
-	int ret;
-
-	ret = register_pernet_device(&ila_net_ops);
-	if (ret)
-		goto exit;
-
-	ret = genl_register_family(&ila_nl_family);
-	if (ret < 0)
-		goto unregister;
-
-	return 0;
-
-unregister:
-	unregister_pernet_device(&ila_net_ops);
-exit:
-	return ret;
-}
-
-void ila_xlat_fini(void)
-{
-	genl_unregister_family(&ila_nl_family);
-	unregister_pernet_device(&ila_net_ops);
-}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v4 net-next 5/6] ila: Flush netlink command to clear xlat table
  2017-12-15 18:27 [PATCH v4 net-next 0/6] net: ILA notification mechanism and fixes Tom Herbert
                   ` (3 preceding siblings ...)
  2017-12-15 18:27 ` [PATCH v4 net-next 4/6] ila: create main ila source file Tom Herbert
@ 2017-12-15 18:27 ` Tom Herbert
  2017-12-15 18:28 ` [PATCH v4 net-next 6/6] ila: Route notify Tom Herbert
  5 siblings, 0 replies; 12+ messages in thread
From: Tom Herbert @ 2017-12-15 18:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, roopa, rohit, Tom Herbert

Add ILA_CMD_FLUSH netlink command to clear the ILA translation table.

Signed-off-by: Tom Herbert <tom@quantonium.net>
---
 include/uapi/linux/ila.h |  1 +
 net/ipv6/ila/ila.h       |  1 +
 net/ipv6/ila/ila_main.c  |  6 +++++
 net/ipv6/ila/ila_xlat.c  | 62 ++++++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/ila.h b/include/uapi/linux/ila.h
index 483b77af4eb8..db45d3e49a12 100644
--- a/include/uapi/linux/ila.h
+++ b/include/uapi/linux/ila.h
@@ -30,6 +30,7 @@ enum {
 	ILA_CMD_ADD,
 	ILA_CMD_DEL,
 	ILA_CMD_GET,
+	ILA_CMD_FLUSH,
 
 	__ILA_CMD_MAX,
 };
diff --git a/net/ipv6/ila/ila.h b/net/ipv6/ila/ila.h
index faba7824ea56..1f747bcbec29 100644
--- a/net/ipv6/ila/ila.h
+++ b/net/ipv6/ila/ila.h
@@ -123,6 +123,7 @@ void ila_xlat_exit_net(struct net *net);
 int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info);
 int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info);
 int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info);
+int ila_xlat_nl_cmd_flush(struct sk_buff *skb, struct genl_info *info);
 int ila_xlat_nl_dump_start(struct netlink_callback *cb);
 int ila_xlat_nl_dump_done(struct netlink_callback *cb);
 int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb);
diff --git a/net/ipv6/ila/ila_main.c b/net/ipv6/ila/ila_main.c
index f6ac6b14577e..18fac76b9520 100644
--- a/net/ipv6/ila/ila_main.c
+++ b/net/ipv6/ila/ila_main.c
@@ -27,6 +27,12 @@ static const struct genl_ops ila_nl_ops[] = {
 		.flags = GENL_ADMIN_PERM,
 	},
 	{
+		.cmd = ILA_CMD_FLUSH,
+		.doit = ila_xlat_nl_cmd_flush,
+		.policy = ila_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
 		.cmd = ILA_CMD_GET,
 		.doit = ila_xlat_nl_cmd_get_mapping,
 		.start = ila_xlat_nl_dump_start,
diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c
index d05de891dfb6..51a15ce50a64 100644
--- a/net/ipv6/ila/ila_xlat.c
+++ b/net/ipv6/ila/ila_xlat.c
@@ -164,9 +164,9 @@ static inline void ila_release(struct ila_map *ila)
 	kfree_rcu(ila, rcu);
 }
 
-static void ila_free_cb(void *ptr, void *arg)
+static void ila_free_node(struct ila_map *ila)
 {
-	struct ila_map *ila = (struct ila_map *)ptr, *next;
+	struct ila_map *next;
 
 	/* Assume rcu_readlock held */
 	while (ila) {
@@ -176,6 +176,11 @@ static void ila_free_cb(void *ptr, void *arg)
 	}
 }
 
+static void ila_free_cb(void *ptr, void *arg)
+{
+	ila_free_node((struct ila_map *)ptr);
+}
+
 static int ila_xlat_addr(struct sk_buff *skb, bool sir2ila);
 
 static unsigned int
@@ -365,6 +370,59 @@ int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info)
 	return 0;
 }
 
+static inline spinlock_t *lock_from_ila_map(struct ila_net *ilan,
+					    struct ila_map *ila)
+{
+	return ila_get_lock(ilan, ila->xp.ip.locator_match);
+}
+
+int ila_xlat_nl_cmd_flush(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net *net = genl_info_net(info);
+	struct ila_net *ilan = net_generic(net, ila_net_id);
+	struct rhashtable_iter iter;
+	struct ila_map *ila;
+	spinlock_t *lock;
+	int ret;
+
+	ret = rhashtable_walk_init(&ilan->xlat.rhash_table, &iter, GFP_KERNEL);
+	if (ret)
+		goto done;
+
+	rhashtable_walk_start(&iter);
+
+	for (;;) {
+		ila = rhashtable_walk_next(&iter);
+
+		if (IS_ERR(ila)) {
+			if (PTR_ERR(ila) == -EAGAIN)
+				continue;
+			ret = PTR_ERR(ila);
+			goto done;
+		} else if (!ila) {
+			break;
+		}
+
+		lock = lock_from_ila_map(ilan, ila);
+
+		spin_lock(lock);
+
+		ret = rhashtable_remove_fast(&ilan->xlat.rhash_table,
+					     &ila->node, rht_params);
+		if (!ret)
+			ila_free_node(ila);
+
+		spin_unlock(lock);
+
+		if (ret)
+			break;
+	}
+
+done:
+	rhashtable_walk_stop(&iter);
+	return ret;
+}
+
 static int ila_fill_info(struct ila_map *ila, struct sk_buff *msg)
 {
 	if (nla_put_u64_64bit(msg, ILA_ATTR_LOCATOR,
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v4 net-next 6/6] ila: Route notify
  2017-12-15 18:27 [PATCH v4 net-next 0/6] net: ILA notification mechanism and fixes Tom Herbert
                   ` (4 preceding siblings ...)
  2017-12-15 18:27 ` [PATCH v4 net-next 5/6] ila: Flush netlink command to clear xlat table Tom Herbert
@ 2017-12-15 18:28 ` Tom Herbert
  2017-12-16 22:18   ` [RFC PATCH] ila: ila_notify() can be static kbuild test robot
                     ` (2 more replies)
  5 siblings, 3 replies; 12+ messages in thread
From: Tom Herbert @ 2017-12-15 18:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, roopa, rohit, Tom Herbert

Implement RTM notifications for ILA routers. This adds support to
ILA LWT to send a netlink RTM message when a router is uses.

THe ILA notify mechanism can be used in two contexts:

- On an ILA forwarding cache a route prefix can be configured to
  do an ILA notification. This method is used when address
  resolution needs to be done on an address.
- One an ILA router an ILA host route entry may include a
  noitification. The purpose of this is to get a notification
  to a userspace daemon to send and ILA redirect

Signed-off-by: Tom Herbert <tom@quantonium.net>
---
 include/uapi/linux/ila.h       |   2 +
 include/uapi/linux/rtnetlink.h |   8 +-
 net/ipv6/ila/ila_lwt.c         | 268 ++++++++++++++++++++++++++++-------------
 3 files changed, 193 insertions(+), 85 deletions(-)

diff --git a/include/uapi/linux/ila.h b/include/uapi/linux/ila.h
index db45d3e49a12..5675f3e71fac 100644
--- a/include/uapi/linux/ila.h
+++ b/include/uapi/linux/ila.h
@@ -19,6 +19,8 @@ enum {
 	ILA_ATTR_CSUM_MODE,			/* u8 */
 	ILA_ATTR_IDENT_TYPE,			/* u8 */
 	ILA_ATTR_HOOK_TYPE,			/* u8 */
+	ILA_ATTR_NOTIFY_DST,			/* flag */
+	ILA_ATTR_NOTIFY_SRC,			/* flag */
 
 	__ILA_ATTR_MAX,
 };
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index d8b5f80c2ea6..8d358a300d8a 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -13,7 +13,8 @@
  */
 #define RTNL_FAMILY_IPMR		128
 #define RTNL_FAMILY_IP6MR		129
-#define RTNL_FAMILY_MAX			129
+#define RTNL_FAMILY_ILA			130
+#define RTNL_FAMILY_MAX			130
 
 /****
  *		Routing/neighbour discovery messages.
@@ -150,6 +151,9 @@ enum {
 	RTM_NEWCACHEREPORT = 96,
 #define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT
 
+	RTM_ADDR_RESOLVE = 98,
+#define RTM_ADDR_RESOLVE RTM_ADDR_RESOLVE
+
 	__RTM_MAX,
 #define RTM_MAX		(((__RTM_MAX + 3) & ~3) - 1)
 };
@@ -676,6 +680,8 @@ enum rtnetlink_groups {
 #define RTNLGRP_IPV4_MROUTE_R	RTNLGRP_IPV4_MROUTE_R
 	RTNLGRP_IPV6_MROUTE_R,
 #define RTNLGRP_IPV6_MROUTE_R	RTNLGRP_IPV6_MROUTE_R
+	RTNLGRP_ILA_NOTIFY,
+#define RTNLGRP_ILA_NOTIFY	RTNLGRP_ILA_NOTIFY
 	__RTNLGRP_MAX
 };
 #define RTNLGRP_MAX	(__RTNLGRP_MAX - 1)
diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c
index 9f1e46a1468e..303c91e3bf76 100644
--- a/net/ipv6/ila/ila_lwt.c
+++ b/net/ipv6/ila/ila_lwt.c
@@ -19,10 +19,15 @@
 struct ila_lwt {
 	struct ila_params p;
 	struct dst_cache dst_cache;
+	u8 hook_type;
 	u32 connected : 1;
-	u32 lwt_output : 1;
+	u32 xlat : 1;
+	u32 notify : 2;
 };
 
+#define ILA_NOTIFY_DST 1
+#define ILA_NOTIFY_SRC 2
+
 static inline struct ila_lwt *ila_lwt_lwtunnel(
 	struct lwtunnel_state *lwt)
 {
@@ -35,6 +40,67 @@ static inline struct ila_params *ila_params_lwtunnel(
 	return &ila_lwt_lwtunnel(lwt)->p;
 }
 
+static size_t ila_rslv_msgsize(void)
+{
+	size_t len =
+		NLMSG_ALIGN(sizeof(struct rtmsg))
+		+ nla_total_size(16)     /* RTA_DST */
+		+ nla_total_size(16)     /* RTA_SRC */
+		;
+
+	return len;
+}
+
+void ila_notify(struct net *net, struct sk_buff *skb, struct ila_lwt *lwt)
+{
+	struct ipv6hdr *ip6h = ipv6_hdr(skb);
+	int flags = NLM_F_MULTI;
+	struct sk_buff *nlskb;
+	struct nlmsghdr *nlh;
+	struct rtmsg *rtm;
+	int err = 0;
+
+	/* Send ILA notification to user */
+	nlskb = nlmsg_new(ila_rslv_msgsize(), GFP_KERNEL);
+	if (!nlskb)
+		return;
+
+	nlh = nlmsg_put(nlskb, 0, 0, RTM_ADDR_RESOLVE, sizeof(*rtm), flags);
+	if (!nlh) {
+		err = -EMSGSIZE;
+		goto errout;
+	}
+
+	rtm = nlmsg_data(nlh);
+	rtm->rtm_family   = AF_INET6;
+	rtm->rtm_dst_len  = 128;
+	rtm->rtm_src_len  = 0;
+	rtm->rtm_tos      = 0;
+	rtm->rtm_table    = RT6_TABLE_UNSPEC;
+	rtm->rtm_type     = RTN_UNICAST;
+	rtm->rtm_scope    = RT_SCOPE_UNIVERSE;
+
+	if (((lwt->notify & ILA_NOTIFY_DST) &&
+	     nla_put_in6_addr(nlskb, RTA_DST, &ip6h->daddr)) ||
+	    ((lwt->notify & ILA_NOTIFY_SRC) &&
+	     nla_put_in6_addr(nlskb, RTA_SRC, &ip6h->saddr))) {
+		nlmsg_cancel(nlskb, nlh);
+		err = -EMSGSIZE;
+		goto errout;
+	}
+
+	nlmsg_end(nlskb, nlh);
+
+	rtnl_notify(nlskb, net, 0, RTNLGRP_ILA_NOTIFY, NULL, GFP_ATOMIC);
+
+	return;
+
+errout:
+	kfree_skb(nlskb);
+	WARN_ON(err == -EMSGSIZE);
+	rtnl_set_sk_err(net, RTNLGRP_ILA_NOTIFY, err);
+}
+
 static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	struct dst_entry *orig_dst = skb_dst(skb);
@@ -46,11 +112,14 @@ static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto drop;
 
-	if (ilwt->lwt_output)
+	if (ilwt->xlat)
 		ila_update_ipv6_locator(skb,
 					ila_params_lwtunnel(orig_dst->lwtstate),
 					true);
 
+	if (ilwt->notify)
+		ila_notify(net, skb, ilwt);
+
 	if (rt->rt6i_flags & (RTF_GATEWAY | RTF_CACHE)) {
 		/* Already have a next hop address in route, no need for
 		 * dest cache route.
@@ -106,11 +175,14 @@ static int ila_input(struct sk_buff *skb)
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto drop;
 
-	if (!ilwt->lwt_output)
+	if (ilwt->xlat)
 		ila_update_ipv6_locator(skb,
 					ila_params_lwtunnel(dst->lwtstate),
 					false);
 
+	if (ilwt->notify)
+		ila_notify(dev_net(dst->dev), skb, ilwt);
+
 	return dst->lwtstate->orig_input(skb);
 
 drop:
@@ -123,6 +195,8 @@ static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
 	[ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, },
 	[ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, },
 	[ILA_ATTR_HOOK_TYPE] = { .type = NLA_U8, },
+	[ILA_ATTR_NOTIFY_DST] = { .type = NLA_FLAG },
+	[ILA_ATTR_NOTIFY_SRC] = { .type = NLA_FLAG },
 };
 
 static int ila_build_state(struct net *net, struct nlattr *nla,
@@ -130,64 +204,73 @@ static int ila_build_state(struct net *net, struct nlattr *nla,
 			   struct lwtunnel_state **ts,
 			   struct netlink_ext_ack *extack)
 {
-	struct ila_lwt *ilwt;
-	struct ila_params *p;
-	struct nlattr *tb[ILA_ATTR_MAX + 1];
-	struct lwtunnel_state *newts;
 	const struct fib6_config *cfg6 = cfg;
-	struct ila_addr *iaddr;
+	struct ila_addr *iaddr = (struct ila_addr *)&cfg6->fc_dst;
 	u8 ident_type = ILA_ATYPE_USE_FORMAT;
 	u8 hook_type = ILA_HOOK_ROUTE_OUTPUT;
+	struct nlattr *tb[ILA_ATTR_MAX + 1];
 	u8 csum_mode = ILA_CSUM_NO_ACTION;
-	bool lwt_output = true;
+	struct lwtunnel_state *newts;
+	struct ila_lwt *ilwt;
+	struct ila_params *p;
 	u8 eff_ident_type;
-	int ret;
+	int err;
 
 	if (family != AF_INET6)
 		return -EINVAL;
 
-	ret = nla_parse_nested(tb, ILA_ATTR_MAX, nla, ila_nl_policy, extack);
-	if (ret < 0)
-		return ret;
+	err = nla_parse_nested(tb, ILA_ATTR_MAX, nla, ila_nl_policy, extack);
+	if (err < 0)
+		return err;
 
-	if (!tb[ILA_ATTR_LOCATOR])
-		return -EINVAL;
+	if (tb[ILA_ATTR_LOCATOR]) {
+		/* Doing ILA translation */
 
-	iaddr = (struct ila_addr *)&cfg6->fc_dst;
+		if (tb[ILA_ATTR_IDENT_TYPE])
+			ident_type = nla_get_u8(tb[ILA_ATTR_IDENT_TYPE]);
 
-	if (tb[ILA_ATTR_IDENT_TYPE])
-		ident_type = nla_get_u8(tb[ILA_ATTR_IDENT_TYPE]);
+		if (ident_type == ILA_ATYPE_USE_FORMAT) {
+			/* Infer identifier type from type field in formatted
+			 * identifier.
+			 */
 
-	if (ident_type == ILA_ATYPE_USE_FORMAT) {
-		/* Infer identifier type from type field in formatted
-		 * identifier.
-		 */
+			if (cfg6->fc_dst_len < 8 *
+			    sizeof(struct ila_locator) + 3) {
+				/* Need to have full locator and at least type
+				 * field included in destination
+				 */
+				return -EINVAL;
+			}
+
+			eff_ident_type = iaddr->ident.type;
+		} else {
+			eff_ident_type = ident_type;
+		}
 
-		if (cfg6->fc_dst_len < 8 * sizeof(struct ila_locator) + 3) {
-			/* Need to have full locator and at least type field
-			 * included in destination
-			 */
+		switch (eff_ident_type) {
+		case ILA_ATYPE_IID:
+			/* Don't allow ILA for IID type */
+			return -EINVAL;
+		case ILA_ATYPE_LUID:
+			break;
+		case ILA_ATYPE_VIRT_V4:
+		case ILA_ATYPE_VIRT_UNI_V6:
+		case ILA_ATYPE_VIRT_MULTI_V6:
+		case ILA_ATYPE_NONLOCAL_ADDR:
+			/* These ILA formats are not supported yet. */
+		default:
 			return -EINVAL;
 		}
 
-		eff_ident_type = iaddr->ident.type;
-	} else {
-		eff_ident_type = ident_type;
-	}
+		csum_mode = nla_get_u8(tb[ILA_ATTR_CSUM_MODE]);
 
-	switch (eff_ident_type) {
-	case ILA_ATYPE_IID:
-		/* Don't allow ILA for IID type */
-		return -EINVAL;
-	case ILA_ATYPE_LUID:
-		break;
-	case ILA_ATYPE_VIRT_V4:
-	case ILA_ATYPE_VIRT_UNI_V6:
-	case ILA_ATYPE_VIRT_MULTI_V6:
-	case ILA_ATYPE_NONLOCAL_ADDR:
-		/* These ILA formats are not supported yet. */
-	default:
-		return -EINVAL;
+		if (csum_mode == ILA_CSUM_NEUTRAL_MAP &&
+		    ila_csum_neutral_set(iaddr->ident)) {
+			/* Don't allow translation if checksum neutral bit is
+			 * configured and it's set in the SIR address.
+			 */
+			return -EINVAL;
+		}
 	}
 
 	if (tb[ILA_ATTR_HOOK_TYPE])
@@ -195,58 +278,62 @@ static int ila_build_state(struct net *net, struct nlattr *nla,
 
 	switch (hook_type) {
 	case ILA_HOOK_ROUTE_OUTPUT:
-		lwt_output = true;
-		break;
 	case ILA_HOOK_ROUTE_INPUT:
-		lwt_output = false;
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	if (tb[ILA_ATTR_CSUM_MODE])
-		csum_mode = nla_get_u8(tb[ILA_ATTR_CSUM_MODE]);
-
-	if (csum_mode == ILA_CSUM_NEUTRAL_MAP &&
-	    ila_csum_neutral_set(iaddr->ident)) {
-		/* Don't allow translation if checksum neutral bit is
-		 * configured and it's set in the SIR address.
-		 */
-		return -EINVAL;
-	}
-
 	newts = lwtunnel_state_alloc(sizeof(*ilwt));
 	if (!newts)
 		return -ENOMEM;
 
 	ilwt = ila_lwt_lwtunnel(newts);
-	ret = dst_cache_init(&ilwt->dst_cache, GFP_ATOMIC);
-	if (ret) {
+
+	err = dst_cache_init(&ilwt->dst_cache, GFP_ATOMIC);
+	if (err) {
 		kfree(newts);
-		return ret;
+		return err;
 	}
 
-	ilwt->lwt_output = !!lwt_output;
+	newts->type = LWTUNNEL_ENCAP_ILA;
 
-	p = ila_params_lwtunnel(newts);
+	switch (hook_type) {
+	case ILA_HOOK_ROUTE_OUTPUT:
+		newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT;
+		break;
+	case ILA_HOOK_ROUTE_INPUT:
+		newts->flags |= LWTUNNEL_STATE_INPUT_REDIRECT;
+		break;
+	}
 
-	p->csum_mode = csum_mode;
-	p->ident_type = ident_type;
-	p->locator.v64 = (__force __be64)nla_get_u64(tb[ILA_ATTR_LOCATOR]);
+	ilwt->hook_type = hook_type;
 
-	/* Precompute checksum difference for translation since we
-	 * know both the old locator and the new one.
-	 */
-	p->locator_match = iaddr->loc;
+	if (tb[ILA_ATTR_NOTIFY_DST])
+		ilwt->notify |= ILA_NOTIFY_DST;
 
-	ila_init_saved_csum(p);
+	if (tb[ILA_ATTR_NOTIFY_SRC])
+		ilwt->notify |= ILA_NOTIFY_SRC;
 
-	newts->type = LWTUNNEL_ENCAP_ILA;
-	newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT |
-			LWTUNNEL_STATE_INPUT_REDIRECT;
+	p = ila_params_lwtunnel(newts);
 
-	if (cfg6->fc_dst_len == 8 * sizeof(struct in6_addr))
-		ilwt->connected = 1;
+	if (tb[ILA_ATTR_LOCATOR]) {
+		ilwt->xlat = true;
+		p->csum_mode = csum_mode;
+		p->ident_type = ident_type;
+		p->locator.v64 = (__force __be64)nla_get_u64(
+							tb[ILA_ATTR_LOCATOR]);
+
+		/* Precompute checksum difference for translation since we
+		 * know both the old locator and the new one.
+		 */
+		p->locator_match = iaddr->loc;
+
+		ila_init_saved_csum(p);
+
+		if (cfg6->fc_dst_len == 8 * sizeof(struct in6_addr))
+			ilwt->connected = 1;
+	}
 
 	*ts = newts;
 
@@ -264,21 +351,32 @@ static int ila_fill_encap_info(struct sk_buff *skb,
 	struct ila_params *p = ila_params_lwtunnel(lwtstate);
 	struct ila_lwt *ilwt = ila_lwt_lwtunnel(lwtstate);
 
-	if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR, (__force u64)p->locator.v64,
-			      ILA_ATTR_PAD))
+	if (ilwt->xlat) {
+		if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR,
+				      (__force u64)p->locator.v64,
+				      ILA_ATTR_PAD))
 		goto nla_put_failure;
 
-	if (nla_put_u8(skb, ILA_ATTR_CSUM_MODE, (__force u8)p->csum_mode))
-		goto nla_put_failure;
+		if (nla_put_u8(skb, ILA_ATTR_CSUM_MODE,
+			       (__force u8)p->csum_mode))
+			goto nla_put_failure;
 
-	if (nla_put_u8(skb, ILA_ATTR_IDENT_TYPE, (__force u8)p->ident_type))
-		goto nla_put_failure;
+		if (nla_put_u8(skb, ILA_ATTR_IDENT_TYPE,
+			       (__force u8)p->ident_type))
+			goto nla_put_failure;
+	}
 
-	if (nla_put_u8(skb, ILA_ATTR_HOOK_TYPE,
-		       ilwt->lwt_output ? ILA_HOOK_ROUTE_OUTPUT :
-					  ILA_HOOK_ROUTE_INPUT))
+	if (nla_put_u8(skb, ILA_ATTR_HOOK_TYPE, ilwt->hook_type))
 		goto nla_put_failure;
 
+	if (ilwt->notify & ILA_NOTIFY_DST)
+		if (nla_put_flag(skb, ILA_ATTR_NOTIFY_DST))
+			goto nla_put_failure;
+
+	if (ilwt->notify & ILA_NOTIFY_SRC)
+		if (nla_put_flag(skb, ILA_ATTR_NOTIFY_SRC))
+			goto nla_put_failure;
+
 	return 0;
 
 nla_put_failure:
@@ -291,6 +389,8 @@ static int ila_encap_nlsize(struct lwtunnel_state *lwtstate)
 	       nla_total_size(sizeof(u8)) +        /* ILA_ATTR_CSUM_MODE */
 	       nla_total_size(sizeof(u8)) +        /* ILA_ATTR_IDENT_TYPE */
 	       nla_total_size(sizeof(u8)) +        /* ILA_ATTR_HOOK_TYPE */
+	       nla_total_size(0) +		   /* ILA_ATTR_NOTIFY_DST */
+	       nla_total_size(0) +		   /* ILA_ATTR_NOTIFY_SRC */
 	       0;
 }
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 net-next 3/6] ila: Call library function alloc_bucket_locks
  2017-12-15 18:27 ` [PATCH v4 net-next 3/6] ila: Call library function alloc_bucket_locks Tom Herbert
@ 2017-12-16 20:47   ` kbuild test robot
  0 siblings, 0 replies; 12+ messages in thread
From: kbuild test robot @ 2017-12-16 20:47 UTC (permalink / raw)
  To: Tom Herbert; +Cc: kbuild-all, davem, netdev, roopa, rohit, Tom Herbert

[-- Attachment #1: Type: text/plain, Size: 1981 bytes --]

Hi Tom,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Tom-Herbert/net-ILA-notification-mechanism-and-fixes/20171217-041013
config: x86_64-randconfig-x019-201751 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

Note: the linux-review/Tom-Herbert/net-ILA-notification-mechanism-and-fixes/20171217-041013 HEAD bdefe11e33bb3662a60476ea17663189974227a0 builds fine.
      It only hurts bisectibility.

All error/warnings (new ones prefixed by >>):

   net/ipv6/ila/ila_xlat.c: In function 'alloc_ila_locks':
>> net/ipv6/ila/ila_xlat.c:39:37: error: 'struct ila_net' has no member named 'xlat'
     return alloc_bucket_spinlocks(&ilan->xlat.locks, &ilan->xlat.locks_mask,
                                        ^~
   net/ipv6/ila/ila_xlat.c:39:56: error: 'struct ila_net' has no member named 'xlat'
     return alloc_bucket_spinlocks(&ilan->xlat.locks, &ilan->xlat.locks_mask,
                                                           ^~
   net/ipv6/ila/ila_xlat.c: In function 'ila_exit_net':
   net/ipv6/ila/ila_xlat.c:630:28: error: 'struct ila_net' has no member named 'xlat'
     free_bucket_spinlocks(ilan->xlat.locks);
                               ^~
   net/ipv6/ila/ila_xlat.c: In function 'alloc_ila_locks':
>> net/ipv6/ila/ila_xlat.c:42:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^

vim +39 net/ipv6/ila/ila_xlat.c

    36	
    37	static int alloc_ila_locks(struct ila_net *ilan)
    38	{
  > 39		return alloc_bucket_spinlocks(&ilan->xlat.locks, &ilan->xlat.locks_mask,
    40					      MAX_LOCKS, LOCKS_PER_CPU,
    41					      GFP_KERNEL);
  > 42	}
    43	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 31625 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC PATCH] ila: ila_notify() can be static
  2017-12-15 18:28 ` [PATCH v4 net-next 6/6] ila: Route notify Tom Herbert
@ 2017-12-16 22:18   ` kbuild test robot
  2017-12-16 22:18   ` [PATCH v4 net-next 6/6] ila: Route notify kbuild test robot
  2017-12-19 16:28   ` Roopa Prabhu
  2 siblings, 0 replies; 12+ messages in thread
From: kbuild test robot @ 2017-12-16 22:18 UTC (permalink / raw)
  To: Tom Herbert; +Cc: kbuild-all, davem, netdev, roopa, rohit, Tom Herbert


Fixes: bdefe11e33bb ("ila: Route notify")
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---
 ila_lwt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c
index 303c91e..fbf6273 100644
--- a/net/ipv6/ila/ila_lwt.c
+++ b/net/ipv6/ila/ila_lwt.c
@@ -51,7 +51,7 @@ static size_t ila_rslv_msgsize(void)
 	return len;
 }
 
-void ila_notify(struct net *net, struct sk_buff *skb, struct ila_lwt *lwt)
+static void ila_notify(struct net *net, struct sk_buff *skb, struct ila_lwt *lwt)
 {
 	struct ipv6hdr *ip6h = ipv6_hdr(skb);
 	int flags = NLM_F_MULTI;

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 net-next 6/6] ila: Route notify
  2017-12-15 18:28 ` [PATCH v4 net-next 6/6] ila: Route notify Tom Herbert
  2017-12-16 22:18   ` [RFC PATCH] ila: ila_notify() can be static kbuild test robot
@ 2017-12-16 22:18   ` kbuild test robot
  2017-12-19 16:28   ` Roopa Prabhu
  2 siblings, 0 replies; 12+ messages in thread
From: kbuild test robot @ 2017-12-16 22:18 UTC (permalink / raw)
  To: Tom Herbert; +Cc: kbuild-all, davem, netdev, roopa, rohit, Tom Herbert

Hi Tom,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Tom-Herbert/net-ILA-notification-mechanism-and-fixes/20171217-041013
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)


Please review and possibly fold the followup patch.

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 net-next 1/6] lwt: Add net to build_state argument
  2017-12-15 18:27 ` [PATCH v4 net-next 1/6] lwt: Add net to build_state argument Tom Herbert
@ 2017-12-19 15:47   ` Roopa Prabhu
  0 siblings, 0 replies; 12+ messages in thread
From: Roopa Prabhu @ 2017-12-19 15:47 UTC (permalink / raw)
  To: Tom Herbert; +Cc: David Miller, netdev, rohit

On Fri, Dec 15, 2017 at 10:27 AM, Tom Herbert <tom@quantonium.net> wrote:
> Users of LWT need to know net if they want to have per net operations
> in LWT.
>
> Signed-off-by: Tom Herbert <tom@quantonium.net>

Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 net-next 6/6] ila: Route notify
  2017-12-15 18:28 ` [PATCH v4 net-next 6/6] ila: Route notify Tom Herbert
  2017-12-16 22:18   ` [RFC PATCH] ila: ila_notify() can be static kbuild test robot
  2017-12-16 22:18   ` [PATCH v4 net-next 6/6] ila: Route notify kbuild test robot
@ 2017-12-19 16:28   ` Roopa Prabhu
  2 siblings, 0 replies; 12+ messages in thread
From: Roopa Prabhu @ 2017-12-19 16:28 UTC (permalink / raw)
  To: Tom Herbert; +Cc: David Miller, netdev, rohit

On Fri, Dec 15, 2017 at 10:28 AM, Tom Herbert <tom@quantonium.net> wrote:
> Implement RTM notifications for ILA routers. This adds support to
> ILA LWT to send a netlink RTM message when a router is uses.
>
> THe ILA notify mechanism can be used in two contexts:
>
> - On an ILA forwarding cache a route prefix can be configured to
>   do an ILA notification. This method is used when address
>   resolution needs to be done on an address.
> - One an ILA router an ILA host route entry may include a
>   noitification. The purpose of this is to get a notification
>   to a userspace daemon to send and ILA redirect
>
> Signed-off-by: Tom Herbert <tom@quantonium.net>
> ---
>  include/uapi/linux/ila.h       |   2 +
>  include/uapi/linux/rtnetlink.h |   8 +-
>  net/ipv6/ila/ila_lwt.c         | 268 ++++++++++++++++++++++++++++-------------
>  3 files changed, 193 insertions(+), 85 deletions(-)
>
> diff --git a/include/uapi/linux/ila.h b/include/uapi/linux/ila.h
> index db45d3e49a12..5675f3e71fac 100644
> --- a/include/uapi/linux/ila.h
> +++ b/include/uapi/linux/ila.h
> @@ -19,6 +19,8 @@ enum {
>         ILA_ATTR_CSUM_MODE,                     /* u8 */
>         ILA_ATTR_IDENT_TYPE,                    /* u8 */
>         ILA_ATTR_HOOK_TYPE,                     /* u8 */
> +       ILA_ATTR_NOTIFY_DST,                    /* flag */
> +       ILA_ATTR_NOTIFY_SRC,                    /* flag */
>
>         __ILA_ATTR_MAX,
>  };
> diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
> index d8b5f80c2ea6..8d358a300d8a 100644
> --- a/include/uapi/linux/rtnetlink.h
> +++ b/include/uapi/linux/rtnetlink.h
> @@ -13,7 +13,8 @@
>   */
>  #define RTNL_FAMILY_IPMR               128
>  #define RTNL_FAMILY_IP6MR              129
> -#define RTNL_FAMILY_MAX                        129
> +#define RTNL_FAMILY_ILA                        130

I don't see this being used, unless I missed it.


> +#define RTNL_FAMILY_MAX                        130
>
>  /****
>   *             Routing/neighbour discovery messages.
> @@ -150,6 +151,9 @@ enum {
>         RTM_NEWCACHEREPORT = 96,
>  #define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT
>
> +       RTM_ADDR_RESOLVE = 98,
> +#define RTM_ADDR_RESOLVE RTM_ADDR_RESOLVE


Its nice that you are trying to add a generic resolver notify
format..., looks good...a few minor comments below for consistency:


your patch adds address resolve notifications with:
- generic notification msg type RTM_ADDR_RESOLVE with route msg format
- On the ILA specific RTNLGRP_ILA_NOTIFY multicast group

Other way to possibly format this for "generic" rtnl netlink resolver is:
- notification msg type RTM_NEWROUTE with route msg format (This is
for consistency: route msg format is always used with RTM_*ROUTE msg
types)
- route entry msg type RTNL_FAMILY_ILA (ie struct rtmsg-> rtm_family
to RTNL_FAMILY_ILA)
- generic address resolution netlink multicast group RTNLGRP_ADDR_RESOLVE_NOTIFY


OR   keep everything "specific" to ILA using the ILA genl channel msg
format and family


Besides that, since you are using the route msg format, you could
potentially s/ADDR_RESOLVE/ROUTE_RESOLVE/g everywhere above.



> +
>         __RTM_MAX,
>  #define RTM_MAX                (((__RTM_MAX + 3) & ~3) - 1)
>  };
> @@ -676,6 +680,8 @@ enum rtnetlink_groups {
>  #define RTNLGRP_IPV4_MROUTE_R  RTNLGRP_IPV4_MROUTE_R
>         RTNLGRP_IPV6_MROUTE_R,
>  #define RTNLGRP_IPV6_MROUTE_R  RTNLGRP_IPV6_MROUTE_R
> +       RTNLGRP_ILA_NOTIFY,
> +#define RTNLGRP_ILA_NOTIFY     RTNLGRP_ILA_NOTIFY
>         __RTNLGRP_MAX
>  };
>  #define RTNLGRP_MAX    (__RTNLGRP_MAX - 1)
> diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c
> index 9f1e46a1468e..303c91e3bf76 100644
> --- a/net/ipv6/ila/ila_lwt.c
> +++ b/net/ipv6/ila/ila_lwt.c
> @@ -19,10 +19,15 @@
>  struct ila_lwt {
>         struct ila_params p;
>         struct dst_cache dst_cache;
> +       u8 hook_type;
>         u32 connected : 1;
> -       u32 lwt_output : 1;
> +       u32 xlat : 1;
> +       u32 notify : 2;
>  };
>
> +#define ILA_NOTIFY_DST 1
> +#define ILA_NOTIFY_SRC 2
> +
>  static inline struct ila_lwt *ila_lwt_lwtunnel(
>         struct lwtunnel_state *lwt)
>  {
> @@ -35,6 +40,67 @@ static inline struct ila_params *ila_params_lwtunnel(
>         return &ila_lwt_lwtunnel(lwt)->p;
>  }
>
> +static size_t ila_rslv_msgsize(void)
> +{
> +       size_t len =
> +               NLMSG_ALIGN(sizeof(struct rtmsg))
> +               + nla_total_size(16)     /* RTA_DST */
> +               + nla_total_size(16)     /* RTA_SRC */
> +               ;
> +
> +       return len;
> +}
> +
> +void ila_notify(struct net *net, struct sk_buff *skb, struct ila_lwt *lwt)
> +{
> +       struct ipv6hdr *ip6h = ipv6_hdr(skb);
> +       int flags = NLM_F_MULTI;
> +       struct sk_buff *nlskb;
> +       struct nlmsghdr *nlh;
> +       struct rtmsg *rtm;
> +       int err = 0;
> +
> +       /* Send ILA notification to user */
> +       nlskb = nlmsg_new(ila_rslv_msgsize(), GFP_KERNEL);
> +       if (!nlskb)
> +               return;
> +
> +       nlh = nlmsg_put(nlskb, 0, 0, RTM_ADDR_RESOLVE, sizeof(*rtm), flags);
> +       if (!nlh) {
> +               err = -EMSGSIZE;
> +               goto errout;
> +       }
> +
> +       rtm = nlmsg_data(nlh);
> +       rtm->rtm_family   = AF_INET6;
> +       rtm->rtm_dst_len  = 128;
> +       rtm->rtm_src_len  = 0;
> +       rtm->rtm_tos      = 0;
> +       rtm->rtm_table    = RT6_TABLE_UNSPEC;
> +       rtm->rtm_type     = RTN_UNICAST;
> +       rtm->rtm_scope    = RT_SCOPE_UNIVERSE;
> +
> +       if (((lwt->notify & ILA_NOTIFY_DST) &&
> +            nla_put_in6_addr(nlskb, RTA_DST, &ip6h->daddr)) ||
> +           ((lwt->notify & ILA_NOTIFY_SRC) &&
> +            nla_put_in6_addr(nlskb, RTA_SRC, &ip6h->saddr))) {
> +               nlmsg_cancel(nlskb, nlh);
> +               err = -EMSGSIZE;
> +               goto errout;
> +       }
> +
> +       nlmsg_end(nlskb, nlh);
> +
> +       rtnl_notify(nlskb, net, 0, RTNLGRP_ILA_NOTIFY, NULL, GFP_ATOMIC);
> +
> +       return;
> +
> +errout:
> +       kfree_skb(nlskb);
> +       WARN_ON(err == -EMSGSIZE);
> +       rtnl_set_sk_err(net, RTNLGRP_ILA_NOTIFY, err);
> +}
> +
>  static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)
>  {
>         struct dst_entry *orig_dst = skb_dst(skb);
> @@ -46,11 +112,14 @@ static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)
>         if (skb->protocol != htons(ETH_P_IPV6))
>                 goto drop;
>
> -       if (ilwt->lwt_output)
> +       if (ilwt->xlat)
>                 ila_update_ipv6_locator(skb,
>                                         ila_params_lwtunnel(orig_dst->lwtstate),
>                                         true);
>
> +       if (ilwt->notify)
> +               ila_notify(net, skb, ilwt);
> +
>         if (rt->rt6i_flags & (RTF_GATEWAY | RTF_CACHE)) {
>                 /* Already have a next hop address in route, no need for
>                  * dest cache route.
> @@ -106,11 +175,14 @@ static int ila_input(struct sk_buff *skb)
>         if (skb->protocol != htons(ETH_P_IPV6))
>                 goto drop;
>
> -       if (!ilwt->lwt_output)
> +       if (ilwt->xlat)
>                 ila_update_ipv6_locator(skb,
>                                         ila_params_lwtunnel(dst->lwtstate),
>                                         false);
>
> +       if (ilwt->notify)
> +               ila_notify(dev_net(dst->dev), skb, ilwt);
> +
>         return dst->lwtstate->orig_input(skb);
>
>  drop:
> @@ -123,6 +195,8 @@ static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
>         [ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, },
>         [ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, },
>         [ILA_ATTR_HOOK_TYPE] = { .type = NLA_U8, },
> +       [ILA_ATTR_NOTIFY_DST] = { .type = NLA_FLAG },
> +       [ILA_ATTR_NOTIFY_SRC] = { .type = NLA_FLAG },
>  };
>
>  static int ila_build_state(struct net *net, struct nlattr *nla,
> @@ -130,64 +204,73 @@ static int ila_build_state(struct net *net, struct nlattr *nla,
>                            struct lwtunnel_state **ts,
>                            struct netlink_ext_ack *extack)
>  {
> -       struct ila_lwt *ilwt;
> -       struct ila_params *p;
> -       struct nlattr *tb[ILA_ATTR_MAX + 1];
> -       struct lwtunnel_state *newts;
>         const struct fib6_config *cfg6 = cfg;
> -       struct ila_addr *iaddr;
> +       struct ila_addr *iaddr = (struct ila_addr *)&cfg6->fc_dst;
>         u8 ident_type = ILA_ATYPE_USE_FORMAT;
>         u8 hook_type = ILA_HOOK_ROUTE_OUTPUT;
> +       struct nlattr *tb[ILA_ATTR_MAX + 1];
>         u8 csum_mode = ILA_CSUM_NO_ACTION;
> -       bool lwt_output = true;
> +       struct lwtunnel_state *newts;
> +       struct ila_lwt *ilwt;
> +       struct ila_params *p;
>         u8 eff_ident_type;
> -       int ret;
> +       int err;
>
>         if (family != AF_INET6)
>                 return -EINVAL;
>
> -       ret = nla_parse_nested(tb, ILA_ATTR_MAX, nla, ila_nl_policy, extack);
> -       if (ret < 0)
> -               return ret;
> +       err = nla_parse_nested(tb, ILA_ATTR_MAX, nla, ila_nl_policy, extack);
> +       if (err < 0)
> +               return err;
>
> -       if (!tb[ILA_ATTR_LOCATOR])
> -               return -EINVAL;
> +       if (tb[ILA_ATTR_LOCATOR]) {
> +               /* Doing ILA translation */
>
> -       iaddr = (struct ila_addr *)&cfg6->fc_dst;
> +               if (tb[ILA_ATTR_IDENT_TYPE])
> +                       ident_type = nla_get_u8(tb[ILA_ATTR_IDENT_TYPE]);
>
> -       if (tb[ILA_ATTR_IDENT_TYPE])
> -               ident_type = nla_get_u8(tb[ILA_ATTR_IDENT_TYPE]);
> +               if (ident_type == ILA_ATYPE_USE_FORMAT) {
> +                       /* Infer identifier type from type field in formatted
> +                        * identifier.
> +                        */
>
> -       if (ident_type == ILA_ATYPE_USE_FORMAT) {
> -               /* Infer identifier type from type field in formatted
> -                * identifier.
> -                */
> +                       if (cfg6->fc_dst_len < 8 *
> +                           sizeof(struct ila_locator) + 3) {
> +                               /* Need to have full locator and at least type
> +                                * field included in destination
> +                                */
> +                               return -EINVAL;
> +                       }
> +
> +                       eff_ident_type = iaddr->ident.type;
> +               } else {
> +                       eff_ident_type = ident_type;
> +               }
>
> -               if (cfg6->fc_dst_len < 8 * sizeof(struct ila_locator) + 3) {
> -                       /* Need to have full locator and at least type field
> -                        * included in destination
> -                        */
> +               switch (eff_ident_type) {
> +               case ILA_ATYPE_IID:
> +                       /* Don't allow ILA for IID type */
> +                       return -EINVAL;
> +               case ILA_ATYPE_LUID:
> +                       break;
> +               case ILA_ATYPE_VIRT_V4:
> +               case ILA_ATYPE_VIRT_UNI_V6:
> +               case ILA_ATYPE_VIRT_MULTI_V6:
> +               case ILA_ATYPE_NONLOCAL_ADDR:
> +                       /* These ILA formats are not supported yet. */
> +               default:
>                         return -EINVAL;
>                 }
>
> -               eff_ident_type = iaddr->ident.type;
> -       } else {
> -               eff_ident_type = ident_type;
> -       }
> +               csum_mode = nla_get_u8(tb[ILA_ATTR_CSUM_MODE]);
>
> -       switch (eff_ident_type) {
> -       case ILA_ATYPE_IID:
> -               /* Don't allow ILA for IID type */
> -               return -EINVAL;
> -       case ILA_ATYPE_LUID:
> -               break;
> -       case ILA_ATYPE_VIRT_V4:
> -       case ILA_ATYPE_VIRT_UNI_V6:
> -       case ILA_ATYPE_VIRT_MULTI_V6:
> -       case ILA_ATYPE_NONLOCAL_ADDR:
> -               /* These ILA formats are not supported yet. */
> -       default:
> -               return -EINVAL;
> +               if (csum_mode == ILA_CSUM_NEUTRAL_MAP &&
> +                   ila_csum_neutral_set(iaddr->ident)) {
> +                       /* Don't allow translation if checksum neutral bit is
> +                        * configured and it's set in the SIR address.
> +                        */
> +                       return -EINVAL;
> +               }
>         }
>
>         if (tb[ILA_ATTR_HOOK_TYPE])
> @@ -195,58 +278,62 @@ static int ila_build_state(struct net *net, struct nlattr *nla,
>
>         switch (hook_type) {
>         case ILA_HOOK_ROUTE_OUTPUT:
> -               lwt_output = true;
> -               break;
>         case ILA_HOOK_ROUTE_INPUT:
> -               lwt_output = false;
>                 break;
>         default:
>                 return -EINVAL;
>         }
>
> -       if (tb[ILA_ATTR_CSUM_MODE])
> -               csum_mode = nla_get_u8(tb[ILA_ATTR_CSUM_MODE]);
> -
> -       if (csum_mode == ILA_CSUM_NEUTRAL_MAP &&
> -           ila_csum_neutral_set(iaddr->ident)) {
> -               /* Don't allow translation if checksum neutral bit is
> -                * configured and it's set in the SIR address.
> -                */
> -               return -EINVAL;
> -       }
> -
>         newts = lwtunnel_state_alloc(sizeof(*ilwt));
>         if (!newts)
>                 return -ENOMEM;
>
>         ilwt = ila_lwt_lwtunnel(newts);
> -       ret = dst_cache_init(&ilwt->dst_cache, GFP_ATOMIC);
> -       if (ret) {
> +
> +       err = dst_cache_init(&ilwt->dst_cache, GFP_ATOMIC);
> +       if (err) {
>                 kfree(newts);
> -               return ret;
> +               return err;
>         }
>
> -       ilwt->lwt_output = !!lwt_output;
> +       newts->type = LWTUNNEL_ENCAP_ILA;
>
> -       p = ila_params_lwtunnel(newts);
> +       switch (hook_type) {
> +       case ILA_HOOK_ROUTE_OUTPUT:
> +               newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT;
> +               break;
> +       case ILA_HOOK_ROUTE_INPUT:
> +               newts->flags |= LWTUNNEL_STATE_INPUT_REDIRECT;
> +               break;
> +       }
>
> -       p->csum_mode = csum_mode;
> -       p->ident_type = ident_type;
> -       p->locator.v64 = (__force __be64)nla_get_u64(tb[ILA_ATTR_LOCATOR]);
> +       ilwt->hook_type = hook_type;
>
> -       /* Precompute checksum difference for translation since we
> -        * know both the old locator and the new one.
> -        */
> -       p->locator_match = iaddr->loc;
> +       if (tb[ILA_ATTR_NOTIFY_DST])
> +               ilwt->notify |= ILA_NOTIFY_DST;
>
> -       ila_init_saved_csum(p);
> +       if (tb[ILA_ATTR_NOTIFY_SRC])
> +               ilwt->notify |= ILA_NOTIFY_SRC;
>
> -       newts->type = LWTUNNEL_ENCAP_ILA;
> -       newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT |
> -                       LWTUNNEL_STATE_INPUT_REDIRECT;
> +       p = ila_params_lwtunnel(newts);
>
> -       if (cfg6->fc_dst_len == 8 * sizeof(struct in6_addr))
> -               ilwt->connected = 1;
> +       if (tb[ILA_ATTR_LOCATOR]) {
> +               ilwt->xlat = true;
> +               p->csum_mode = csum_mode;
> +               p->ident_type = ident_type;
> +               p->locator.v64 = (__force __be64)nla_get_u64(
> +                                                       tb[ILA_ATTR_LOCATOR]);
> +
> +               /* Precompute checksum difference for translation since we
> +                * know both the old locator and the new one.
> +                */
> +               p->locator_match = iaddr->loc;
> +
> +               ila_init_saved_csum(p);
> +
> +               if (cfg6->fc_dst_len == 8 * sizeof(struct in6_addr))
> +                       ilwt->connected = 1;
> +       }
>
>         *ts = newts;
>
> @@ -264,21 +351,32 @@ static int ila_fill_encap_info(struct sk_buff *skb,
>         struct ila_params *p = ila_params_lwtunnel(lwtstate);
>         struct ila_lwt *ilwt = ila_lwt_lwtunnel(lwtstate);
>
> -       if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR, (__force u64)p->locator.v64,
> -                             ILA_ATTR_PAD))
> +       if (ilwt->xlat) {
> +               if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR,
> +                                     (__force u64)p->locator.v64,
> +                                     ILA_ATTR_PAD))
>                 goto nla_put_failure;
>
> -       if (nla_put_u8(skb, ILA_ATTR_CSUM_MODE, (__force u8)p->csum_mode))
> -               goto nla_put_failure;
> +               if (nla_put_u8(skb, ILA_ATTR_CSUM_MODE,
> +                              (__force u8)p->csum_mode))
> +                       goto nla_put_failure;
>
> -       if (nla_put_u8(skb, ILA_ATTR_IDENT_TYPE, (__force u8)p->ident_type))
> -               goto nla_put_failure;
> +               if (nla_put_u8(skb, ILA_ATTR_IDENT_TYPE,
> +                              (__force u8)p->ident_type))
> +                       goto nla_put_failure;
> +       }
>
> -       if (nla_put_u8(skb, ILA_ATTR_HOOK_TYPE,
> -                      ilwt->lwt_output ? ILA_HOOK_ROUTE_OUTPUT :
> -                                         ILA_HOOK_ROUTE_INPUT))
> +       if (nla_put_u8(skb, ILA_ATTR_HOOK_TYPE, ilwt->hook_type))
>                 goto nla_put_failure;
>
> +       if (ilwt->notify & ILA_NOTIFY_DST)
> +               if (nla_put_flag(skb, ILA_ATTR_NOTIFY_DST))
> +                       goto nla_put_failure;
> +
> +       if (ilwt->notify & ILA_NOTIFY_SRC)
> +               if (nla_put_flag(skb, ILA_ATTR_NOTIFY_SRC))
> +                       goto nla_put_failure;
> +
>         return 0;
>
>  nla_put_failure:
> @@ -291,6 +389,8 @@ static int ila_encap_nlsize(struct lwtunnel_state *lwtstate)
>                nla_total_size(sizeof(u8)) +        /* ILA_ATTR_CSUM_MODE */
>                nla_total_size(sizeof(u8)) +        /* ILA_ATTR_IDENT_TYPE */
>                nla_total_size(sizeof(u8)) +        /* ILA_ATTR_HOOK_TYPE */
> +              nla_total_size(0) +                 /* ILA_ATTR_NOTIFY_DST */
> +              nla_total_size(0) +                 /* ILA_ATTR_NOTIFY_SRC */
>                0;
>  }
>
> --
> 2.11.0
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-12-19 16:28 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-15 18:27 [PATCH v4 net-next 0/6] net: ILA notification mechanism and fixes Tom Herbert
2017-12-15 18:27 ` [PATCH v4 net-next 1/6] lwt: Add net to build_state argument Tom Herbert
2017-12-19 15:47   ` Roopa Prabhu
2017-12-15 18:27 ` [PATCH v4 net-next 2/6] ila: Fix use of rhashtable walk in ila_xlat.c Tom Herbert
2017-12-15 18:27 ` [PATCH v4 net-next 3/6] ila: Call library function alloc_bucket_locks Tom Herbert
2017-12-16 20:47   ` kbuild test robot
2017-12-15 18:27 ` [PATCH v4 net-next 4/6] ila: create main ila source file Tom Herbert
2017-12-15 18:27 ` [PATCH v4 net-next 5/6] ila: Flush netlink command to clear xlat table Tom Herbert
2017-12-15 18:28 ` [PATCH v4 net-next 6/6] ila: Route notify Tom Herbert
2017-12-16 22:18   ` [RFC PATCH] ila: ila_notify() can be static kbuild test robot
2017-12-16 22:18   ` [PATCH v4 net-next 6/6] ila: Route notify kbuild test robot
2017-12-19 16:28   ` Roopa Prabhu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.